You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
2.2 KiB
50 lines
2.2 KiB
package com.mydreamjob.messaging;
|
|
|
|
import org.springframework.data.domain.Page;
|
|
import org.springframework.data.domain.Pageable;
|
|
import org.springframework.data.jpa.repository.JpaRepository;
|
|
import org.springframework.data.jpa.repository.Lock;
|
|
import org.springframework.data.jpa.repository.Modifying;
|
|
import org.springframework.data.jpa.repository.Query;
|
|
import org.springframework.data.repository.query.Param;
|
|
import org.springframework.stereotype.Repository;
|
|
import jakarta.persistence.LockModeType;
|
|
|
|
import java.time.LocalDateTime;
|
|
import java.util.List;
|
|
|
|
@Repository
|
|
public interface MessageRepository extends JpaRepository<Message, Long> {
|
|
|
|
Page<Message> findByConversationIdOrderByCreatedAtDesc(Long conversationId, Pageable pageable);
|
|
|
|
List<Message> findByConversationIdInOrderByConversationIdAscCreatedAtDesc(List<Long> conversationIds);
|
|
|
|
/**
|
|
* 条件更新未命中后的当前读,用于区分并发请求已完成撤回与真实冲突。
|
|
* PESSIMISTIC_WRITE 强制读取提交后的最新行,避免 MySQL REPEATABLE READ 使用旧快照。
|
|
*/
|
|
@Lock(LockModeType.PESSIMISTIC_WRITE)
|
|
@Query("select m from Message m where m.id = :messageId")
|
|
java.util.Optional<Message> findCurrentByIdForRecall(@Param("messageId") Long messageId);
|
|
|
|
@Modifying(clearAutomatically = true, flushAutomatically = true)
|
|
@Query("""
|
|
update Message m
|
|
set m.status = 'RECALLED',
|
|
m.content = :placeholder,
|
|
m.recalledAt = :recalledAt,
|
|
m.version = m.version + 1
|
|
where m.id = :messageId
|
|
and m.conversationId = :conversationId
|
|
and m.senderUserId = :senderUserId
|
|
and m.status = 'SENT'
|
|
and m.version = :expectedVersion
|
|
""")
|
|
int recallIfCurrent(@Param("messageId") Long messageId,
|
|
@Param("conversationId") Long conversationId,
|
|
@Param("senderUserId") Long senderUserId,
|
|
@Param("expectedVersion") Long expectedVersion,
|
|
@Param("placeholder") String placeholder,
|
|
@Param("recalledAt") LocalDateTime recalledAt);
|
|
}
|
|
|