一、事务
1.事务特性:acid
2.事务的并发问题
脏读
幻读
不可重复读
3.事务隔离级别
1:读未提交
2:读已提交
4:可重复读
8:串行化
二、spring封装了事务管理代码
1.事务操作
打开事务
提交事务
回滚事务
2.事务操作对象
因为在不同平台,操作事务的代码各不相同,spring提供了一个接口:PlatformTransactionManager(事务操作接口)
PlatformTransactionManager
DataSourceTransactionManager
HibernateTransacionManager
注意:在spring中使用事务管理最为核心的对象就是TransactionManager
3.spring管理事务的属性介绍
(1)事务的隔离级别
1:读未提交
2:读已提交
4:可重复读
8:串行化
(2)事务是否只读
true:只读
false:可操作
(3)事务的传播行为
决定业务方法之间调用时,事务应该如何处理问题
PROPAGATION_REQUIRED:支持当前事务,如果不存在,就新建一个(默认)
PROPAGATION_SUPPORTS:支持当前事务,如果不存在,就不使用事务
PROPAGATION_MANDATORY:支持当前事务,如果不存在,抛出异常
PROPAGATION_REQUIRES_NEW:如果事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果事务存在,挂起当前事务
PROPAGATION_NEVER:以非事务方式运行,如果事务存在,抛出异常
PROPAGATION_NESTED:如果当前事务存在,则嵌套事务执行
三、事务演示
accountDao.java
package cn.itcast.dao;
public interface AccountDao {
//加钱
void increaseMoney(Integer id,Double money);
//减钱
void decreaseMoney(Integer id,Double money);
}
accountDaoImpl.java
package cn.itcast.dao;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{
@Override
public void increaseMoney(Integer id,Double money) {
getJdbcTemplate().update("update t_account set money = money + ? where id = ?", money,id);
}
@Override
public void decreaseMoney(Integer id,Double money) {
getJdbcTemplate().update("update t_account set money = money - ? where id = ?", money,id);
}
}
accountService.java
package cn.itcast.service;
public interface AccountService {
//转账方法
void transfer(Integer from,Integer to,Double money);
}
accountServiceImpl.java
package cn.itcast.service;
import cn.itcast.dao.AccountDao;
public class AccountServiceImpl implements AccountService {
private AccountDao ad;
@Override
public void transfer(Integer from, Integer to, Double money) {
//减钱
ad.decreaseMoney(from, money);
//加钱
ad.increaseMoney(to, money);
}
public AccountDao getAd() {
return ad;
}
public void setAd(AccountDao ad) {
this.ad = ad;
}
}
Demo
package cn.itcast.test;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import cn.itcast.service.AccountService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {
@Resource(name = "accountService")
private AccountService as;
@Test
public void fun1() {
as.transfer(1, 2, 100d);
}
}
applicationContext.xml
配置文件依赖关系
dataSource----->AccountDao----->AccountService
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd ">
<!-- 1.连接池 -->
<bean name = "dataSource" class = "com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value = "jdbc:mysql://localhost:3306/spring_day3?useSSL=false&serverTimezone=GMT&allowPublicKeyRetrieval=true"></property>
<property name="driverClass" value = "com.mysql.cj.jdbc.Driver"></property>
<property name="user" value = "root"></property>
<property name="password" value = "jzb19981128"></property>
</bean>
<!-- 2.注入accountDao -->
<bean name = "accountDao" class = "cn.itcast.dao.AccountDaoImpl">
<property name="dataSource" ref = "dataSource"></property>
</bean>
<!-- 3.Service -->
<bean name = "accountService" class = "cn.itcast.service.AccountServiceImpl">
<property name = "ad" ref = "accountDao"></property>
</bean>
</beans>
四、Spring管理事务方式
1.编码式
PlatformTransationManager将核心事务管理器配置进(了解)
AccountServiceImpl.java
package cn.itcast.service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import cn.itcast.dao.AccountDao;
public class AccountServiceImpl implements AccountService {
private AccountDao ad;
private TransactionTemplate tt;
@Override
public void transfer(final Integer from, final Integer to,final Double money) {
tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus arg0) {
//减钱
ad.decreaseMoney(from, money);
//加钱
ad.increaseMoney(to, money);
}
});
//1.打开事务
//2.调用doInTransactionWithResult方法
//3.提交事务
}
public AccountDao getAd() {
return ad;
}
public void setAd(AccountDao ad) {
this.ad = ad;
}
public TransactionTemplate getTt() {
return tt;
}
public void setTt(TransactionTemplate tt) {
this.tt = tt;
}
}
applicationContext.java
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd ">
<!-- 事务核心管理器,封装了所有事务操作,依赖有连接池 -->
<bean name = "trasactionManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propery name = "dataSource" ref = "dataSource"></propery>
</bean>
<!-- 事务模板对象 -->
<bean name = "transaction" class = "org.springframework.transaction.support.TransactionTemplate">
<propery name = "trasactionManager" ref = "trasationManager"></propery>
</bean>
<!-- 1.连接池 -->
<bean name = "dataSource" class = "com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value = "jdbc:mysql://localhost:3306/spring_day3?useSSL=false&serverTimezone=GMT&allowPublicKeyRetrieval=true"></property>
<property name="driverClass" value = "com.mysql.cj.jdbc.Driver"></property>
<property name="user" value = "root"></property>
<property name="password" value = "jzb19981128"></property>
</bean>
<!-- 2.注入accountDao -->
<bean name = "accountDao" class = "cn.itcast.dao.AccountDaoImpl">
<property name="dataSource" ref = "dataSource"></property>
</bean>
<!-- 3.Service -->
<bean name = "accountService" class = "cn.itcast.service.AccountServiceImpl">
<property name = "ad" ref = "accountDao"></property>
<property name = "tt" ref = "TransactionTemplate"></property>
</bean>
</beans>
Demo.java
package cn.itcast.test;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import cn.itcast.service.AccountService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {
@Resource(name = "accountService")
private AccountService as;
@Test
public void fun1() {
as.transfer(1, 2, 100d);
}
}
2.xml配置式(aop)–重点
导包(aop,aspect,aop联盟,weaving织入包)
导入新的约束(tx)
beans
context:读取properties配置
aop配置:aop
tx配置事务通知
配置通知
配置将通知织入目标对象
3.注解配置(aop)–重点
导包(aop,aspect,aop联盟,weaving织入包)
导入新的约束(tx)
beans
context:读取properties配置
aop配置:aop
tx配置事务通知
开启注解管理事务
使用注解
方法内注解
方法外注解: