Spring    事务管理(一)

来源:互联网 发布:win10 企业版激活软件 编辑:程序博客网 时间:2024/06/06 05:13
什么是事务?
事务指的是逻辑上的一组操作,这组操作要么全部成功iowa,要么全部失败。

事务的特性:
原子性是指事物是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
一致性指事物前后数据的完整性必须保持一致
隔离性指多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数据要相互隔离
持久性是指一个事务被提交,它对数据库中数据的改变是持久性的,即使数据库发生故障也不应该对其有任何影响



Spring接口介绍-事务管理
.Spring事务管理高层抽象主要包括3个接口
.PlatformTransactionManager
事务管理器
.TransactionDefinition
事务定义信息(隔离,传播,超时,只读)
.TransactionStatus
事务具体运行状态


PlatformTransactionManager
.Spring为不同的持久层框架提供了不同PlatformTransactionManager接口实现
Spring <wbr> <wbr> <wbr> <wbr>事务管理(一)




脏读:一个事务读取了另一个事务改写但还未提交的数据,如果这些数据被回滚,则读到的数据是无效的
不可重复读:在同一事务中,多次读取同一数据返回的结果有所不同
幻读:一个事务读取了几行记录后,另一个事务插入一些记录幻读就发生了。在后来查询中,第一个事务就会发生有些原来没有的记录 
TransactionDefinition
隔离级别
Spring <wbr> <wbr> <wbr> <wbr>事务管理(一)

mysql的默认级别(DEFAULT)=REPEATABLE_READ,oracle默认采用READ_COMMITTED


Spring <wbr> <wbr> <wbr> <wbr>事务管理(一)

事务的传播行为(七种):
Spring <wbr> <wbr> <wbr> <wbr>事务管理(一)




.Spring支持两种方式事务管理
 - 编程式的事务管理
.在实际应用中很少使用
.通过TransactionTemplate手动管理事务
 - 使用XML配置声明式事务
.开发中推荐使用
.Spring的声明式事务是通过AOP实现的




首先,通用配置:
log4j.properties:
log4j.rootLogger=INFO,logfile,stdout
          
#log4j.logger.org.springframework.web.servlet=INFO,db

#log4j.logger.org.springframework.beans.factory.xml=INFO
#log4j.logger.com.neam.stum.user=INFO,db

#log4j.appender.stdout=org.apache.log4j.ConsoleAppender
#log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
#log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-ddHH\:mm\:ss} %p [%c] %X{remoteAddr}  %X{remotePort} %X{remoteHost}  %X{remoteUser}operator\:[\u59D3\u540D\:%X{userName} \u5DE5\u53F7\:%X{userId}]message\:《%m》%n

#write log into file
log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logfile.Threshold=warn
log4j.appender.logfile.File=${webapp.root}\\logs\\Spring-transaction.log
log4j.appender.logfile.DatePattern=.yyyy-MM-dd
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=[SpringTransaction]%d{yyyy-MM-dd HH\:mm\:ss} %X{remoteAddr} %X{remotePort} %m %n


#display in console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Threshold=info
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[SpringTransaction]%d{yyyy-MM-dd HH\:mm\:ss} %X{remoteAddr} %X{remotePort} %m %n


jdbc.properties:
jdbc.password=123456
jdbc.url=jdbc:mysql://localhost:3306/spring-transaction
jdbc.username=root
jdbc.driverClass=com.mysql.jdbc.Driver


编程式事务管理:
applicationContext.xml:
《!-- 引入外部的属性文件 --》
《context:property-placeholderlocation="classpath:jdbc.properties"/》
《!-- 配置c3p0连接池 --》
《bean id="dataSource"class="com.mchange.v2.c3p0.ComboPooledDataSource"》
《property name="driverClass" value="${jdbc.driverClass}"/》
《property name="jdbcUrl" value="${jdbc.url}" /》
《property name="user" value="${jdbc.username}" /》
《property name="password" value="${jdbc.password}" /》
《/bean》
《!-- 配置业务层类 --》
《bean id="accountService"class="cn.muke.spring.demol.AccountServiceImpl"》
《property name="accountDao" ref="accountDao" /》
《!-- 注入事务管理的模版 --》
《property name="transactionTemplate"ref="transactionTemplate"》《/property》
《/bean》
《!-- 配置DAO类(简化,会自动配置JdbcTemplate) --》                                       
《bean id="accountDao"class="cn.muke.spring.demol.AccountDaoImpl"》
《property name="dataSource" ref="dataSource" /》
《/bean》
《!-- 配置事物管理器 --》
《bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"》
《property name="dataSource" ref="dataSource"》《/property》
《/bean》
《!-- 配置事物管理的模版:Spring为了简化事务管理的代码 --》
《bean id="transactionTemplate"class="org.springframework.transaction.support.TransactionTemplate"》
《property name="transactionManager"ref="transactionManager"》《/property》
《/bean》



public interface AccountDao {
public void outMoney(String out,Double money);
public void inMoney(String in,Double money);
}


public class AccountDaoImpl extends JdbcDaoSupport implementsAccountDao {

public void outMoney(String out, Double money) {
String sql = "update account set money = money - ? where name= ?";
this.getJdbcTemplate().update(sql, money,out);
}

 
public void inMoney(String in, Double money) {
String sql = "update account set money = money + ? where name= ?";
this.getJdbcTemplate().update(sql, money,in);
}

}



public interface AccountService {
public void transfer(String out,String in,Double money);
}

public class AccountServiceImpl implements AccountService{

public void setTransactionTemplate(TransactionTemplatetransactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}

// 注入转账Dao的类
private AccountDao accountDao;
//注入事务管理的模版
private TransactionTemplate transactionTemplate;
@Override
public void transfer(final String out,final String in,finalDouble money) {
transactionTemplate.execute(newTransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatustransactionStatus) {
accountDao.outMoney(out, money);
//int i = 1/0;
accountDao.inMoney(in, money);
}
});
}

}


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemol1 {
@Resource(name="accountService")
private AccountService accountService;
@Test
public void demol(){
accountService.transfer("aaa", "bbb", 200d);
}
}
结果test,一个+200一个-200,解除除0注释,数据没有任何变化
0 0
原创粉丝点击