日期:2014-05-16  浏览次数:20596 次

spring事务example Test
package com.vxichina.test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

/***
 * 
 * @author harbor
 *
 */
public class JDBCTemplateTransactionTest {
	public static final String CREATE_TABLE_SQL = "create table transactionTestTable (id int    IDENTITY PRIMARY KEY, name varchar(100))";
	public static final String DROP_TABLE_SQL = "drop table transactionTestTable";
	public static final String INSERT_SQL = "insert into transactionTestTable(name) values(?)";
	public static final String COUNT_SQL = "select count(*) from transactionTestTable";

	public static void main(String[] args) {
		/*
		 * 
		 * 事务必需满足ACID(原子性、一致性、隔离性和持久性)特性,缺一不可:

		    原子性(Atomicity):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做;
		    一致性(Consistency):在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是处于正确的状态,即数据完整性约束没有被破坏;如银行转帐,A转帐给B,必须保证A的钱一定转给B,一定不会出现A的钱转了但B没收到,否则数据库的数据就处于不一致(不正确)的状态。
		    隔离性(Isolation):并发事务执行之间无影响,在一个事务内部的操作对其他事务是不产生影响,这需要事务隔离级别来指定隔离性;
		    持久性(Durability):事务一旦执行成功,它对数据库的数据的改变必须是永久的,不会因比如遇到系统故障或断电造成数据不一致或丢失。
		
		   在实际项目开发中数据库操作一般都是并发执行的,即有多个事务并发执行,并发执行就可能遇到问题,目前常见的问题如下:
		
		    丢失更新:两个事务同时更新一行数据,最后一个事务的更新会覆盖掉第一个事务的更新,从而导致第一个事务更新的数据丢失,这是由于没有加锁造成的;
		    脏读:一个事务看到了另一个事务未提交的更新数据;
		    不可重复读:在同一事务中,多次读取同一数据却返回不同的结果;也就是有其他事务更改了这些数据;
		    幻读:一个事务在执行过程中读取到了另一个事务已提交的插入数据;即在第一个事务开始时读取到一批数据,但此后另一个事务又插入了新数据并提交,此时第一个事务又读取这批数据但发现多了一条,即好像发生幻觉一样。

		    未提交读(Read Uncommitted):最低隔离级别,一个事务能读取到别的事务未提交的更新数据,很不安全,可能出现丢失更新、脏读、不可重复读、幻读;
		    提交读(Read Committed):一个事务能读取到别的事务提交的更新数据,不能看到未提交的更新数据,不可能可能出现丢失更新、脏读,但可能出现不可重复读、幻读;
		    可重复读(Repeatable Read):保证同一事务中先后执行的多次查询将返回同一结果,不受其他事务影响,可能可能出现丢失更新、脏读、不可重复读,但可能出现幻读;
		    序列化(Serializable):最高隔离级别,不允许事务并发执行,而必须串行化执行,最安全,不可能出现更新、脏读、不可重复读、幻读。
		
		    隔离级别越高,数据库事务并发执行性能越差,能处理的操作越少。因此在实际项目开发中为了考虑并发性能一般使用提交读隔离级别,它能避免丢失更新和脏读,
		  尽管不可重复读和幻读不能避免,但可以在可能出现的场合使用悲观锁或乐观锁来解决这些问题。
		  
		Spring中Propagation类的事务属性详解:
	    PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 
	    PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。 
	    PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。 
	    PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
	    PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 
	    PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。 
	    PROPAGATION_NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。
    <tx:advice id="txAdvice" transaction-manager="txManager">  
    <tx:attributes>  
               <tx:method name="save*" propagation="REQUIRED" />  
               <tx:method name="add*" propagation="REQUIRED" />  
               <tx:method name="create*" propagation="REQUIRED" />  
               <tx:method name="insert*" propagation="REQUIRED" />  
               <tx:method name="update*" propagation="REQUIRED" />  
               <tx:method name="merge*" propagation="REQUIRED" />  
               <tx:method name="del*" propagation="REQUIRED" />  
               <tx:method name="remove*" propagation="REQUIRED" />  
               <tx:method name="put*" propagation="REQUIRED" />  
               <tx:method name="get*" propagation="SUPPORTS" read-only="true" />  
               <tx:method name="count*" propagation="SUPPORTS" read-only="true" />  
              <tx:method name="find*" propagation="SUPPORTS" read-only="true" />  
              <tx:method name="list*" propagation="SUPPORTS" read-only="true" />  
              <tx:method name="*" propagation="SUPPORTS" read-only="true" />  
           </tx:attributes>  
    </t