1. Propagation (propagation properties of transactions) Propagation : The key property determines which method the proxy should add transactional behavior to. The most important part of such a property is the propagation behavior. The following options are available: PROPAGATION_REQUIRED--support the current transaction, if there is no current transaction, create a new transaction. This is the most common choice. PROPAGATION_SUPPORTS--Support the current transaction, if there is no current transaction, it will be executed in a non-transactional manner. PROPAGATION_MANDATORY--Supports the current transaction, if there is no current transaction, an exception is thrown. PROPAGATION_REQUIRES_NEW--Create a new transaction, if there is a current transaction, suspend the current transaction. PROPAGATION_NOT_SUPPORTED--Perform the operation in a non-transactional manner, suspending the current transaction if there is a current transaction. PROPAGATION_NEVER--Execute in a non-transactional manner, throwing an exception if there is currently a transaction. 1: PROPAGATION_REQUIRED Join the current transaction to be executed is not in another transaction, then start a new transaction For example, if the transaction level of ServiceB.methodB is defined as PROPAGATION_REQUIRED, then when ServiceA.methodA is executed, ServiceA.methodA has already started a transaction. At this time, ServiceB.methodB is called. ServiceB.methodB sees that it is already running in ServiceA.methodA Inside the transaction, no new transaction will be started. And if ServiceA.methodA runs and finds that he is not in a transaction, he will assign himself a transaction. This way, if an exception occurs in ServiceA.methodA or anywhere within ServiceB.methodB, the transaction will be rolled back. Even if ServiceB.methodB's transaction has been Submit, but ServiceA.methodA will be rolled back next fail, and ServiceB.methodB will also be rolled back 2: PROPAGATION_SUPPORTS If it is currently in a transaction, that is, it is running in the form of a transaction. If it is not currently in a transaction, it is running in a non-transactional form. 3: PROPAGATION_MANDATORY Must run within a transaction. That is, he can only be called by a parent transaction. Otherwise, he will throw an exception 4: PROPAGATION_REQUIRES_NEW This is rather convoluted. For example, we design the transaction level of ServiceA.methodA to be PROPAGATION_REQUIRED, and the transaction level of ServiceB.methodB to be PROPAGATION_REQUIRES_NEW. Then when ServiceB.methodB is executed, the transaction where ServiceA.methodA is located will be suspended, ServiceB.methodB will start a new transaction, and after the transaction of ServiceB.methodB is completed, He just continued. The difference between him and the PROPAGATION_REQUIRED transaction is the degree of rollback of the transaction. Because ServiceB.methodB is a new transaction, then there is two different transactions. If ServiceB.methodB has been submitted, then ServiceA.methodA fails and rolls back, but ServiceB.methodB will not roll back. Rollback if ServiceB.methodB fails, If the exception he throws is caught by ServiceA.methodA, the ServiceA.methodA transaction may still commit. 5: PROPAGATION_NOT_SUPPORTED Transactions are not currently supported. For example, the transaction level of ServiceA.methodA is PROPAGATION_REQUIRED, while the transaction level of ServiceB.methodB is PROPAGATION_NOT_SUPPORTED, Then when ServiceB.methodB is executed, the transaction of ServiceA.methodA is suspended, and he finishes running in a non-transactional state, and then continues the transaction of ServiceA.methodA. 6: PROPAGATION_NEVER 不能在事务中运行。假设ServiceA.methodA的事务级别是PROPAGATION_REQUIRED, 而ServiceB.methodB的事务级别是PROPAGATION_NEVER , 那么ServiceB.methodB就要抛出异常了。 7: PROPAGATION_NESTED 理解Nested的关键是savepoint。他与PROPAGATION_REQUIRES_NEW的区别是,PROPAGATION_REQUIRES_NEW另起一个事务,将会与他的父事务相互独立, 而Nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,他也要回滚的。 而Nested事务的好处是他有一个savepoint。 ***************************************** ServiceA { /** * 事务属性配置为 PROPAGATION_REQUIRED */ void methodA() { try { //savepoint ServiceB.methodB(); //PROPAGATION_NESTED 级别 } catch (SomeException) { // 执行其他业务, 如 ServiceC.methodC(); } } } ******************************************** 也就是说ServiceB.methodB失败回滚,那么ServiceA.methodA也会回滚到savepoint点上,ServiceA.methodA可以选择另外一个分支,比如 ServiceC.methodC,继续执行,来尝试完成自己的事务。 但是这个事务并没有在EJB标准中定义。 二、Isolation Level(事务隔离等级): 1、Serializable:最严格的级别,事务串行执行,资源消耗最大; 2、REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。 3、READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。 4、Read Uncommitted:保证了读取过程中不会读取到非法数据。隔离级别在于处理多事务的并发问题。 我们知道并行可以提高数据库的吞吐量和效率,但是并不是所有的并发事务都可以并发运行,这需要查看数据库教材的可串行化条件判断了。 这里就不阐述。 我们首先说并发中可能发生的3中不讨人喜欢的事情 1: Dirty reads--读脏数据。也就是说,比如事务A的未提交(还依然缓存)的数据被事务B读走,如果事务A失败回滚,会导致事务B所读取的的数据是错误的。 2: non-repeatable reads--数据不可重复读。比如事务A中两处读取数据-total-的值。在第一读的时候,total是100,然后事务B就把total的数据改成 200,事务A再读一次,结果就发现,total竟然就变成200了,造成事务A数据混乱。 3: phantom reads--幻象读数据,这个和non-repeatable reads相似,也是同一个事务中多次读不一致的问题。但是non-repeatable reads的不一致是因为他所要取的数据集被改变了(比如total的数据),但是phantom reads所要读的数据的不一致却不是他所要读的数据集改变,而是他的条件数据集改变。比如Select account.id where account.name="ppgogo*",第一次读去了6个符合条件的id,第二次读取的时候,由于事务b把一个帐号的名字由"dd"改成"ppgogo1",结果取出来了7个数据。
三、readOnly 事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。 这是一个最优化提示。在一些情况下,一些事务策略能够起到显著的最优化效果,例如在使用Object/Relational映射工具(如:Hibernate或TopLink)时避免dirty checking(试图“刷新”)。 四、Timeout 在事务属性中还有定义“timeout”值的选项,指定事务超时为几秒。在JTA中,这将被简单地传递到J2EE服务器的事务协调程序,并据此得到相应的解释
20110112 数据库提供了四种事务隔离级别, 不同的隔离级别采用不同的锁类开来实现. |
Propagation properties and transaction isolation level of transactions in spring
Guess you like
Origin http://43.154.161.224:23101/article/api/json?id=325979245&siteId=291194637
Ranking