刘光辉
4 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="jnpf.dmsMapper.DmsFileExpiryMapper">
    <resultMap id="Item" type="jnpf.dmsEntity.storage.expiry.DmsFileExpiryItem">
        <id column="file_version_id" property="fileVersionId" typeHandler="jnpf.dmsDatabase.DmsUuidTypeHandler"/>
        <result column="document_id" property="documentId" typeHandler="jnpf.dmsDatabase.DmsUuidTypeHandler"/>
        <result column="tenant_id" property="tenantId"/>
        <result column="lifecycle_status" property="lifecycleStatus"/>
        <result column="effective_from" property="effectiveFrom"/>
        <result column="effective_to" property="effectiveTo"/>
        <result column="expiry_cursor" property="expiryCursor"/>
        <result column="search_task_id" property="searchTaskId"/>
    </resultMap>
    <!-- A cleanup receipt alone does not prove that older code updated the business version. -->
    <sql id="NEEDS_PROJECTION">
        NOT EXISTS (SELECT 1 FROM public.dms_file_expiry_cleanup c
            WHERE c.tenant_id=s.tenant_id AND c.file_version_id=s.file_version_id)
        OR EXISTS (SELECT 1 FROM public.dms_wenjian_ziyuan r
            JOIN public.dms_wenjian_banben b ON b.f_tenant_id=r.f_tenant_id AND b.wenjian_id=r.f_id
                AND b.f_id=r.dangqian_banben_id AND b.f_delete_mark IS NULL
            WHERE r.f_tenant_id=s.tenant_id AND r.f_delete_mark IS NULL AND b.biz_status='effective'
              AND b.wenjian_zhongxin_banben_id=CAST(s.file_version_id AS TEXT))
    </sql>
    <select id="candidates" resultMap="Item">
        SELECT s.tenant_id, s.document_id, s.file_version_id, s.lifecycle_status, s.effective_from, s.effective_to,
            s.effective_to AS expiry_cursor
        FROM public.dms_version_states s
        WHERE s.effective_to &lt;= statement_timestamp()
          AND (s.lifecycle_status = 'EFFECTIVE' OR (s.lifecycle_status = 'EXPIRED' AND (<include refid="NEEDS_PROJECTION"/>)))
        <if test="after != null">
          AND (s.effective_to, s.tenant_id, s.file_version_id) &gt;
              (#{after.expiryCursor}, #{after.tenantId}, #{after.fileVersionId,jdbcType=OTHER,typeHandler=jnpf.dmsDatabase.DmsUuidTypeHandler})
        </if>
        ORDER BY s.effective_to, s.tenant_id, s.file_version_id LIMIT #{limit}
    </select>
    <!-- Lock the document first, matching activation and validity changes. Discovery never locks states. -->
    <select id="tryLockDocument" resultType="java.util.UUID">
        SELECT id FROM public.dms_documents WHERE tenant_id=#{tenantId}
          AND id=#{documentId,jdbcType=OTHER,typeHandler=jnpf.dmsDatabase.DmsUuidTypeHandler}
        FOR UPDATE SKIP LOCKED
    </select>
    <select id="dueState" resultMap="Item">
        SELECT tenant_id, document_id, file_version_id, lifecycle_status, effective_from, effective_to
        FROM public.dms_version_states s WHERE tenant_id=#{tenantId}
          AND file_version_id=#{fileVersionId,jdbcType=OTHER,typeHandler=jnpf.dmsDatabase.DmsUuidTypeHandler}
          AND lifecycle_status IN ('EFFECTIVE','EXPIRED') AND effective_to &lt;= statement_timestamp()
          AND (lifecycle_status &lt;&gt; 'EXPIRED' OR (<include refid="NEEDS_PROJECTION"/>))
    </select>
    <insert id="enqueueCleanup">
        INSERT INTO public.dms_file_expiry_cleanup (tenant_id, file_version_id)
        VALUES (#{tenantId}, #{fileVersionId,jdbcType=OTHER,typeHandler=jnpf.dmsDatabase.DmsUuidTypeHandler})
        ON CONFLICT (tenant_id, file_version_id) DO NOTHING
    </insert>
    <select id="cleanupCandidates" resultMap="Item">
        SELECT tenant_id, file_version_id, search_task_id FROM public.dms_file_expiry_cleanup
        WHERE completed_at IS NULL AND next_attempt_at &lt;= statement_timestamp()
        ORDER BY next_attempt_at, tenant_id, file_version_id LIMIT #{limit}
    </select>
    <select id="lockCleanup" resultMap="Item">
        SELECT tenant_id, file_version_id, search_task_id FROM public.dms_file_expiry_cleanup
        WHERE tenant_id=#{tenantId} AND file_version_id=#{fileVersionId,jdbcType=OTHER,typeHandler=jnpf.dmsDatabase.DmsUuidTypeHandler}
          AND completed_at IS NULL AND next_attempt_at &lt;= statement_timestamp()
        FOR UPDATE SKIP LOCKED
    </select>
    <update id="updateCleanup">
        UPDATE public.dms_file_expiry_cleanup SET search_task_id=#{item.searchTaskId},
            completed_at=CASE WHEN #{done} THEN statement_timestamp() ELSE NULL END,
            attempts=attempts+1, last_error=#{error}, updated_at=statement_timestamp(),
            next_attempt_at=statement_timestamp() + (#{delay} * INTERVAL '1 second')
        WHERE tenant_id=#{item.tenantId}
          AND file_version_id=#{item.fileVersionId,jdbcType=OTHER,typeHandler=jnpf.dmsDatabase.DmsUuidTypeHandler}
    </update>
</mapper>