# 八种事务类型及事务传播机制 * 八种事务类型 | 事务类型 | 说明 | | --- | --- | | PROPAGATION_REQUIRED | 表示如果当前事务存在,则支持当前事务。否则,会启动一个新的事务。xorm中默认事务类型。 | | PROPAGATION_SUPPORTS | 表示如果当前事务存在,则支持当前事务,如果当前没有事务,就以非事务方式执行。 | | PROPAGATION_MANDATORY | 表示如果当前事务存在,则支持当前事务,如果当前没有事务,则返回事务嵌套错误。 | | PROPAGATION_REQUIRES_NEW | 表示新建一个全新Session开启一个全新事务,如果当前存在事务,则把当前事务挂起。 | | PROPAGATION_NOT_SUPPORTED | 表示以非事务方式执行操作,如果当前存在事务,则新建一个Session以非事务方式执行操作,把当前事务挂起。 | | PROPAGATION_NEVER | 表示以非事务方式执行操作,如果当前存在事务,则返回事务嵌套错误。 | | PROPAGATION_NESTED | 表示如果当前事务存在,则在嵌套事务内执行,如嵌套事务回滚,则只会在嵌套事务内回滚,不会影响当前事务。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。 | | PROPAGATION_NOT_REQUIRED | 表示如果当前没有事务,就新建一个事务,否则返回错误。 | * 事务传播机制 <b>1. PROPAGATION_REQUIRED </b> PROPAGATION_REQUIRED类型的事务,如果当前Session中如果已经开启了数据库事务,并且有程序在控制这个事务。那么在处理 REQUIRED 行为时将会忽略 commit/rollback 操作,这是加入已有事务的特征。当前Session中如果没有事务那么会开启新一个新事务。 | 时间| 事务1 | 事务2| | --- | --- |--- | |T1| 开始事务| | |T2| 操作1... | | |T3| |加入事务1| |T4 | |操作2...| |T5 |操作3...| | |T6 |递交事务| | 说明: 事务1是当前Session中存在的事务,事务2是们我们新建的PROPAGATION_REQUIRED类型的事务 <b>2.PROPAGATION_SUPPORTS </b> ROPAGATION_SUPPORTS类型的事务和PROPAGATION_REQUIRED类型的事务的区别在于,当前Session中如果没有事务那么PROPAGATION_SUPPORTS类型的事务会以非事务方式执行。 <b>3. PROPAGATION_MANDATORY</b> PROPAGATION_MANDATORY类型的事务和PROPAGATION_REQUIRED类型的事务的区别在于,当前Session中如果没有事务那么PROPAGATION_MANDATORY类型的事务在开启时会返回事务嵌套错误。 <b>4. PROPAGATION_REQUIRES_NEW</b> PROPAGATION_REQUIRES_NEW类型的事务强调事务独立性。它保证了每个事务状态管理范围内锁使用的数据库连接是彼此不一样的。例如独立事务会满足,事务1中存在事务2,当事务2递交的时候不影响事务1。两个事务之间不存在相互关联关系。开启事务2时,事务1会挂起,等事务2提交完成后,会恢复事务1,继续执行。当前Session中如果没有事务那么会开启新一个新事务。 | 时间| 事务1 | 事务2| | --- | --- |--- | |T1| 开始事务| | |T2| 操作1... | | |T3| |挂起事务1| |T4| |开始事务| |T5 | |操作2...| |T6 | |递交事务| |T7 | |恢复事务1| |T8 |操作3...| | |T9 |递交事务| | 说明: 事务1是当前Session中存在的事务,事务2是们我们新建的PROPAGATION_REQUIRES_NEW类型的事务。事务1和事务2存在于不同Session中,事务执行结束后,请注意在适当的位置关闭事务所存在的Session。 <b>5. PROPAGATION_NOT_SUPPORTED</b> PROPAGATION_NOT_SUPPORTED类型的事务与PROPAGATION_REQUIRES_NEW类型事务的区别在于,PROPAGATION_NOT_SUPPORTED类型的事务在挂起当前Session中已经开启了的数据库事务之后不会在尝试开启新的事务。 | 时间| 事务1 (开启事务)| 事务2(非事务)| | --- | --- |--- | |T1| 开始事务| | |T2| 操作1... | | |T3| |挂起事务1| |T4 | |操作2...| |T4 | |操作3...| |T5 | |恢复事务1| |T6 |操作4...| | |T7 |递交事务| | 说明:事务1和事务2存在于不同Session中,事务执行结束后,请注意在适当的位置关闭事务所存在的Session。 <b>6. PROPAGATION_NEVER</b> PROPAGATION_NEVER类型的事务,强调了非事务。一旦发现当前Session中已存在的事务,则返回事务嵌套错误。 <b>7. PROPAGATION_NESTED</b> PROPAGATION_NESTED类型的事务,如果当前Session中存在的事务,则运行开启一个嵌套的事务,创建一个回滚的保存点。如果当前Session没有活动事务,则创建一个新事务。内部事务的回滚不会对外部事务造成影响。如外部事务回滚,则内部嵌套事务一起回滚。 | 时间| 事务1 | 事务2| | --- | --- |--- | |T1| 开始事务| | |T2| 操作1... | | |T3| |创建事务保存点| |T4 | |操作2...| |T5 | |递交/回滚保存点| |T6 |操作3...| | |T7 |递交事务| | <b>8. PROPAGATION_NOT_REQUIRED</b> PROPAGATION_NOT_REQUIRED类型事务与PROPAGATION_REQUIRED的事务正好相反,如果当前Session中如果已经开启了数据库事务,则返回错误,否则,会启动一个新的事务。 该类型可以保障创建的事务只会在嵌套事务层级中是顶层事务,否则则会返回错误。