spring声明式事务管理代码示例(五种写法)

12220171030

package com.tiger.service;

import java.sql.SQLException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
/**
 * 方式 一:编程式事务
 * @author tiger
 * @date 2017年10月30日
 */
@Component
public class CountService1 {

	@Autowired
	private JdbcTemplate jdbcTemplate;
	@Autowired
	private DataSourceTransactionManager txManager;
	/**
	 * 对转账操作进行事务管理
	 * @param method
	 * @throws SQLException
	 */
	public void log1() throws SQLException {
		
		DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
		//设置隔离级别
		definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
		
		TransactionStatus ts = txManager.getTransaction(definition);
		try {
			String getsql = "update ts set count=count+100 where name = 'A'";
			jdbcTemplate.update(getsql);
			
			//人工制造异常测试
//			int a = 100/0;
			
			String updatesql = "update ts set count=count-100 where name = 'B'";
			jdbcTemplate.update(updatesql);
			
			//提交事务
			txManager.commit(ts);
		}catch (Exception e) {
			System.err.println("发生异常,数据回滚 "+e.getMessage());
			txManager.rollback(ts);
		}
	}
}
package com.tiger.main;

import java.sql.SQLException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.tiger.service.CountService1;
import com.tiger.service.CountService2_3_4;

/**
 *	测试
 * @author tiger
 * @date 2017年10月25日
 */
public class Mian {

	public static void main(String[] args) throws SQLException {
		
		ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
		
//		test1(ctx);
		
//		test2(ctx);
		
		test3_4(ctx);
		
	}
	
	/**
	 * 方式一
	 * @throws SQLException
	 */
	public static void test1(ApplicationContext ctx) throws SQLException {
		CountService1 logService = (CountService1) ctx.getBean("countService1");
		logService.log1();
	}
	
	/**
	 * 方式二:注意,必须把方式三xml配置给注释掉
	 * @throws SQLException
	 */
	public static void test2(ApplicationContext ctx) throws SQLException {
		CountService2_3_4 logService = (CountService2_3_4) ctx.getBean("countTransactionProxy");
		logService.log2_3_4();
	}
	
	/**
	 * 方式三(AOP) & 方式四(注解)
	 * @throws SQLException
	 */
	public static void test3_4(ApplicationContext ctx) throws SQLException {
		CountService2_3_4 logService = (CountService2_3_4) ctx.getBean("countService2_3_4");
		logService.log2_3_4();
	}
	
	
}package com.tiger.service;

import java.sql.SQLException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import org.springframework.transaction.annotation.*;
/**
 * 方式二 & 方式 三 & 方式 四:声明式事务,配置beans.xml文件
 * @author tiger
 * @date 2017年10月30日
 */
@Component
public class CountService2_3_4 {

	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	/**
	 * 对转账操作进行事务管理
	 * @param method
	 * @throws SQLException
	 */
//	@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED)
	public void log2_3_4() throws SQLException {
		
			String getsql = "update ts set count=count+100 where name = 'A'";
			jdbcTemplate.update(getsql);
			
			//人工制造异常测试
			int a = 100/0;
			
			String updatesql = "update ts set count=count-100 where name = 'B'";
			jdbcTemplate.update(updatesql);
	}
}

   
   

   
   

	
    
    
	
    
    

	
    
    
	
    
    

	
    
    
	
    
    

	
    
    
	
    
    

	
    
    
	
    
    

	
    
    

	
    
    
	
    
    
		
     
     
		
     
     
		
     
     
		
     
     
		
     
     
		
     
     
			
      
      
				
       
       
				
       
       
         PROPAGATION_REQUIRED,ISOLATION_DEFAULT 
       
			
      
      
		
     
     
	
    
    

	
    
    
	
    
    
		
     
     
			
      
      
		
     
     
	
    
    
	
    
    
	
    
    
		
     
     
	
    
    

	
    
    
	
    
    


   
   
#Let's talk about this file in src catalog
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/book?useUnicode=true&characterEncoding=utf8&useSSL=true
jdbc.username=root
jdbc.password=123456

#SET FOREIGN_KEY_CHECKS=0;
#
#-- ----------------------------
#-- Table structure for ts
#-- ----------------------------
#DROP TABLE IF EXISTS `ts`;
#CREATE TABLE `ts` (
#  `name` varchar(20) DEFAULT NULL,
#  `count` int(11) DEFAULT NULL
#) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#
#-- ----------------------------
#-- Records of ts
#-- ----------------------------
#INSERT INTO `ts` VALUES ('A', '1400');
#INSERT INTO `ts` VALUES ('B', '600');package com.tiger.bean;

import org.springframework.stereotype.Component;

@Component
public class Count {

	private String name;
	private Integer count;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getCount() {
		return count;
	}
	public void setCount(Integer count) {
		this.count = count;
	}
	public Count(String name, Integer count) {
		super();
		this.name = name;
		this.count = count;
	}
	public Count() {
		super();
	}
	@Override
	public String toString() {
		return "Log [name=" + name + ", count=" + count + "]";
	}
}
12220171030

1、事务的概念:一组逻辑执行单元(多条sql语句),要么全部执行成功,要么失败。

2、作用:保证数据的完整性,因为很多复杂的事物要分步进行,但它们组成了一个整体,要么整体生效,要么整体失效。这种思想反映到数据库上,就是多条SQL语句,要么所有执行成功,要么所有执行失败。

3、事务四个特征:

   1)、原子性(Atomicity):表示组成一个事务的多个数据库操作是一个不可分割的原子单元

   2)、一致性(Consistency):事务操作成功后,数据库存所处的状态和它的业务规则是一致的,即数据不会被破坏

   3)、隔离性(Isolation):在并发数据操作时,不同的事务拥有各自的数据空间,它们的操作不会对对方产生干扰。准确地说,并非要做到完全无干扰程度,隔离级别越高,数据一致性越好,但并发性越弱

   4)、持久性(Durability):一旦事务提交成功后,事务中所有的数据操作都必须被持久化到数据库中。即使在提交事务后,数据库马上崩溃,在数据库重启时,也必须保证能够通过某种机制恢复数据

4、隔离性:解决数据并发的问题

5、并发现象:

   1)、脏读【数据破坏】

   2)、不可重复读【数据完好,两次读取的数据不同,第二次比第一次少,第二次读取的数据才是真实数据】

   3)、幻象读【数据完好,两次读取的数据不同,第二次比第一次多,第二次读取的数据才是真实数据】

   4)、第一类丢失更新【数据破坏,数据变少】

   5)、第二类丢失更新【数据破坏,数据变多】

5、隔离级别

   1)、读未提交数据(READ UNCOMMITED):避免第一类丢失更新

   2)、读已提交数据(READ COMMITED):避免脏读、第一类丢失更新的发生(默认[isolation=Isolation.DEFAULT])

   3)、读可重复数据(REPEATABLE READ):只允许幻象

   4)、串行读取数据(SERIALIZABLE):隔离最佳,并发性能差。

6、Spring如何管理事务:亮点 --> 声明式事务管理,不需要硬编码,只需在xml配置文件中描述事务如何操作,最终交由底层封装好的工具类完成。

7、Spring管理事务核心API:

   1)、TransactionDefinition:描述事务的属性

      (1)、隔离级别

      (2)、传播行为(事务中包含另外一个事务,默认沿用之前的事务[注解写法:propagation=Propagation.REQUIRED])

           REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
           SUPPORTS:如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。
           MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
           REQUIRES_NEW:总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。     
           NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务
           NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常
           NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行     
      
      (3)、设置事务只读

   2)、PlatformTransactionManager:管理事务

      (1)、创建事务

      (2)、提交事务

      (3)、事务的回滚

   3)、TransactionStatus:描述事务状态

      (1)、描述事务状态

      (2)、获取当前事务是不是一个新事务

      (3)、获取当前事务是否只读
      
8、Spring管理事务的 4 种编写方式:

   1)、编程式实现事务管理

   2)、基于TransactionProxy的声明式事务管理

   3)、基于 
   
   
    
     命名空间的声明式事务管理

   4)、基于 @Transactional 的声明式事务管理  
      
      #must import jar log4j-1.2.17.jar
log4j.rootLogger=DEBUG,R,A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d %5p [%t] (%F:%L) - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=d:/pimc_log4j.log
log4j.appender.R.MaxFileSize=1000KB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d %5p [%t] (%F:%L) - %m%n





   
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ljt-tiger

thanks

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值