Spring トランザクション分離レベルとトランザクション伝播プロパティ

1. Propagation (トランザクションの伝播特性)

伝播: key 属性は、プロキシがトランザクション動作を追加するメソッドを決定します。このようなプロパティの最も重要な部分は伝播動作です。次のオプションが利用可能です: PROPAGATION_REQUIRED -- 現在のトランザクションをサポートします。現在のトランザクションがない場合は、新しいトランザクションを作成します。これが最も一般的な選択です。
PROPAGATION_SUPPORTS -- 現在のトランザクションをサポートします。現在のトランザクションがない場合は、非トランザクション方式で実行されます。
PROPAGATION_MANDATORY -- 現在のトランザクションをサポートします。現在のトランザクションがない場合、例外がスローされます。
PROPAGATION_REQUIRES_NEW -- 新しいトランザクションを作成します。現在のトランザクションがある場合は、現在のトランザクションを一時停止します。
PROPAGATION_NOT_SUPPORTED -- 非トランザクション方式で操作を実行します。現在のトランザクションがある場合は、現在のトランザクションを一時停止します。
PROPAGATION_NEVER -- 非トランザクション方式で実行し、トランザクションが現在存在する場合は例外をスローします。

1: PROPAGATION_REQUIRED は
、現在実行中で別のトランザクションにないトランザクションに参加し、新しいトランザクションを開始します。
たとえば、ServiceB.methodB のトランザクション レベルが PROPAGATION_REQUIRED として定義されている場合、ServiceA.methodA が実行されると、
ServiceA.methodAトランザクションが完了すると、この時点で ServiceB.methodB が呼び出されます。ServiceB.methodB は、
ServiceA.methodA のトランザクション内ですでに実行されていると認識するため、新しいトランザクションは開始しません。そして、ServiceA.methodA の実行中にトランザクションに参加していないことが判明した場合、自分自身にトランザクションを割り当てます。
このように、ServiceA.methodA または ServiceB.methodB のどこかで例外が発生した場合、トランザクションはロールバックされます。ServiceB.methodB のトランザクションが
コミットされていても、次の失敗で ServiceA.methodA がロールバックされる場合でも、ServiceB.methodB はロールバックされます。

2: PROPAGATION_SUPPORTS が
現在トランザクション内にある場合はトランザクションとして実行され、現在トランザクション内にない場合は非トランザクションとして実行されます。


3: PROPAGATION_MANDATORY は
トランザクションで実行する必要があります。つまり、1 つの親トランザクションからのみ呼び出すことができます。それ以外の場合、彼は例外をスローします

4: PROPAGATION_REQUIRES_NEW
これはさらに複雑です。たとえば、ServiceA.methodA のトランザクション レベルを PROPAGATION_REQUIRED に、ServiceB.methodB のトランザクション レベルを PROPAGATION_REQUIRES_NEW に設計した場合、ServiceB.methodB が
実行されると、ServiceA.methodA が存在するトランザクションは一時停止され、 ServiceB.methodB が新しいトランザクションを開始します。ServiceB.methodB のトランザクションが完了するまで待ってから、
実行を続行してください。彼と PROPAGATION_REQUIRED の違いは、トランザクションのロールバックの程度です。ServiceB.methodB は新しいトランザクションであるため、
2 つの異なるトランザクションが存在します。ServiceB.methodB が送信されている場合、ServiceA.methodA はロールバックに失敗し、ServiceB.methodB はロールバックされません。ServiceB.methodA が失敗してロールバックした場合でも、
ServiceB.methodA がスローする例外が ServiceA.methodA によってキャッチされた場合、ServiceA.methodA トランザクションはコミットされる可能性があります。

5: PROPAGATION_NOT_SUPPORTED は
現在トランザクションをサポートしていません。たとえば、ServiceA.methodA のトランザクション レベルが PROPAGATION_REQUIRED、ServiceB.methodB のトランザクション レベルが PROPAGATION_NOT_SUPPORTED の
場合、ServiceB.methodB が実行されると、ServiceA.methodA のトランザクションは一時停止され、非トランザクション状態で実行されます。 、その後 ServiceA .methodA のトランザクションを続行します。

6: PROPAGATION_NEVER は
トランザクション内で実行できません。ServiceA.methodA のトランザクション レベルが PROPAGATION_REQUIRED、ServiceB.methodB のトランザクション レベルが PROPAGATION_NEVER であるとする
と、ServiceB.methodB は例外をスローします。

7: PROPAGATION_NESTED
ネストを理解するための鍵はセーブポイントです。彼と PROPAGATION_REQUIRES_NEW の違いは、PROPAGATION_REQUIRES_NEW は親トランザクションから独立した新しいトランザクションを作成するの
に対し、Nested のトランザクションは親トランザクションに依存しており、彼のコミットは親トランザクションと一緒に送信されることです。つまり、親トランザクションが最後にロールバックすると、親トランザクションもロールバックされます。
ネストされたトランザクションの利点は、セーブポイントがあることです。
*******************************************
サービスA {

/**
* トランザクション属性は PROPAGATION_REQUIRED として設定されています
*/
void methodA() { try { //savepoint ServiceB.methodB(); //PROPAGATION_NESTED level } catch (SomeException) { // ServiceC.methodC などの他のサービスを実行します(); } }






}
********************************************
也就是说ServiceB.methodB失败回滚,那么ServiceA.methodA也会回滚到savepoint点上,ServiceA.methodA可以选择另外一个分支,比如
ServiceC.methodC,继续执行,来尝试完成自己的事务。
但是这个事务并没有在EJB标准中定义。

Spring事务的隔离级别
 1. ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
      另外四个与JDBC的隔离级别相对应
 2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。
      这种隔离级别会产生脏读,不可重复读和幻像读。
 3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
 4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
      它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
 5. ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。
      除了防止脏读,不可重复读外,还避免了幻像读。

什么是脏数据,脏读,不可重复读,幻觉读?
 脏读: 指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,
     另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据, 那么另外一
     个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。
    
 不可重复读: 指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。
             那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据
             可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
            
 幻觉读: 指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及
         到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,
         以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

おすすめ

転載: blog.csdn.net/xiaojiahao_kevin/article/details/52233237