Spring事务&JDBC

四大特性

  • 原子性
  • 一致性
  • 隔离性
  • 持久性

隔离级别

  • 读未提交
  • 读已提交
  • 可重复读
  • 可串行化

传播行为

保证方法中使用了同一事务;

  • PROPAGATION_REQUIRED:
  • 支持当前事务;如果当前方法中不存在事务,则创建一个新的事务;
  • PROPAGATION_SUPPORTS
  • 默认支持当前事务;如果当前方法中不存在事务,则以非事务的方式运行;
  • PROPAGATION_MANDATORY
  • 默认来说支持当前事务;如果没有事务,则抛出异常。

保证方式中使用了不同的事务;

  • PROPAGATION_REQUIRES_NEW
  • 如果当前方法中存在事务,则不用当前事务;否则创建一个新的事务;
  • PROPAGATION_NOT_SUPPORTED
  • 如果当前方法中存在事务,则不用;如果没有,则以非事务方式进行运行;
  • PROPAGATION_NEVER
  • 如果当前方法中有事务,则抛出异常;保证当前方法以非事务方式运行。

嵌套事务

  • PROPAGATION_NESTED
  • 循环事务。如果当前方法存在事务,则在嵌套事务内运行;

使用

平台事务管理器

PlatformTransactionManager
作用:用来配置和管理事务的;
需要配置: JdbcTransactionManager 、 Hibernate TrancationManager;

事务定义

TransactionDefinition.class
作用:里面规定了隔离级别以及传播行为还有部分其他定义信息

事务状态

TransactionStatus.class
查看当前事务状态,将管理事务状态内容记录在当前类中。
hasSavepoint() : 是否有回滚点;嵌套事务;
flush (): 刷新的事务的作用。

操作

使用平台事务管理器根据事务定义信息将定义的事务进行管理,随着事务的不断变化,将事务的状态记录在事务状态类中。

事务类型

编程式事务

编程式事务可以实现程序代码中出现异常事务回滚的操作,但是修改了源代码,因此一般不使用。

xml配置:

XML 复制代码
<!-- 配置平台事务管理器,将其交给spring容器管理:
此处使用jdbctransactionManager:
-->
<bean id="transactionManager"
class="org.springframework.jdbc.support.JdbcTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事务模板 -->
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager">
</property>
</bean>

声明式事务

  • 采用aop的方式来进行操作,不修改的源代码的基础上进行事务管理。推荐
  • 需要在xml文档中添加tx命名空间和约束

xml文件

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
">
<!-- 开启包扫描:开启后的包中的类添加@Component就可以交给spring容器管理
注意:
1、此处写的是包名;
2、多个的话使用,进行分隔;
-->
<context:component-scan base-package="cn.ry.dao"></context:componentscan>
<!-- 由于jdbcTemplate的使用需要用到dataSource,因此提前配置dataSource;
考虑到dataSource采用的是连接池------德鲁伊连接池;druid;需要引入jar;
-->
<!-- 需要读取properties中的数据源:
需要在properties文件中的属性前添加别名:a.
-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${a.driverClassName}">
</property>
<property name="url" value="${a.url}"></property>
<property name="username" value="${a.username}"></property>
<property name="password" value="${a.password}"></property>
</bean>
<!-- springjdbc核心类:jdbcTemplate -->
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置平台事务管理器,将其交给spring容器管理:
此处使用jdbctransactionManager:
-->
<bean id="transactionManager"
class="org.springframework.jdbc.support.JdbcTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置增强:事务的增强; -->
注解版本*
xml中简单配置
<tx:advice id="tx1" transaction-manager="transactionManager">
<tx:attributes>
<!--
isolation:隔离级别;
no-rollback-for:指定不回滚的异常;
rollback-for:指定异常进行回滚;
propagation:传播行为;
read-only:是否只读;
timeout:超时;
-->
<tx:method name="zhuanzhang"
isolation="DEFAULT"
propagation="REQUIRED"
read-only="false"
/>
</tx:attributes>
</tx:advice>
<!-- aop配置 织入 -->
<aop:config>
<aop:pointcut expression="execution(* cn.ry.service.*.*.*(..))"
id="p1"/>
<aop:advisor advice-ref="tx1" pointcut-ref="p1"/>
</aop:config>
</beans>

注解版本

xml中简单配置

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
">
<!-- 开启包扫描:开启后的包中的类添加@Component就可以交给spring容器管理
注意:
1、此处写的是包名;
2、多个的话使用,进行分隔;
-->
<context:component-scan base-package="cn.ry.dao"></context:componentscan>
<!-- 由于jdbcTemplate的使用需要用到dataSource,因此提前配置dataSource;
考虑到dataSource采用的是连接池------德鲁伊连接池;druid;需要引入jar;
-->
<!-- 需要读取properties中的数据源:
需要在properties文件中的属性前添加别名:a.
-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${a.driverClassName}">
</property>
<property name="url" value="${a.url}"></property>
<property name="username" value="${a.username}"></property>
<property name="password" value="${a.password}"></property>
</bean>
<!-- springjdbc核心类:jdbcTemplate -->
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置平台事务管理器,将其交给spring容器管理:
此处使用jdbctransactionManager:
-->
<bean id="transactionManager"
class="org.springframework.jdbc.support.JdbcTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事务标签开启注解驱动: -->
<tx:annotation-driven/>
</beans>

java代码

java 复制代码
package cn.ry.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import cn.ry.dao.ZhangDanDao;
import cn.ry.service.ZdService;
@Service
public class ZdServiceImpl implements ZdService {
@Autowired
private ZhangDanDao dao;
@Override
@Transactional(propagation = Propagation.REQUIRED)
public int zhuanzhang() {
// TODO Auto-generated method stub
//调用dao实现:
int i = dao.delete();
int j =1/0;
int i1= dao.add();
return i+i1;
}
}

事务注意事项

  • 在spring中方法基本上使用public来修饰,需要注意,事务中也是public修饰,如果不是可能事务会失效;
  • 同类中方法相互调用会导致事务失效;
  • 被final修饰的方法也会导致事务失效。

SpringJDBC

  • 使用spring-jdbc去代替之前的dao的封装;
  • 需要引入spring-jdbc.jar包,还有spring-tx.jar包;
  • spring-jdbc中的核心也就是JdbcTemplate类,模板模式;

xml配置

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
">
<!-- 开启包扫描:开启后的包中的类添加@Component就可以交给spring容器管理
注意:
1、此处写的是包名;
2、多个的话使用,进行分隔;
-->
<!-- 由于jdbcTemplate的使用需要用到dataSource,因此提前配置dataSource;
考虑到dataSource采用的是连接池------德鲁伊连接池;druid;需要引入jar;
-->
<!-- 需要读取properties中的数据源:
需要在properties文件中的属性前添加别名:a.
-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${a.driverClassName}">
</property>
<property name="url" value="${a.url}"></property>
<property name="username" value="${a.username}"></property>
<property name="password" value="${a.password}"></property>
</bean>
<!-- springjdbc核心类:jdbcTemplate -->
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>

java代码

java 复制代码
package cn.ry.test;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.sun.xml.internal.ws.encoding.DataHandlerDataSource;
import cn.ry.pojo.ZhangDan;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext-jdbc.xml"})
public class TestJDBC {
@Autowired
private DataSource dataSource;
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void f1() {
//查询返回集合: list<Map>;
List<Map<String, Object>> list = jdbcTemplate.queryForList("select
id,name,money from zhangdan");
System.out.println(list);
//查询数量: 要求返回出来的是一列;
Integer i = jdbcTemplate.queryForObject("select count(1) from zhangdan
where id=?", Integer.class,3);
System.out.println(i);
//jdbc中的dml;
int update = jdbcTemplate.update("update zhangdan set money = money-?
where id=?",300,3);
System.out.println(update);
}
}
相关推荐
公贵买其鹿11 分钟前
List深拷贝后,数据还是被串改
java
xlsw_3 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹4 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭5 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫5 小时前
泛型(2)
java
超爱吃士力架5 小时前
邀请逻辑
java·linux·后端
南宫生5 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石5 小时前
12/21java基础
java
李小白665 小时前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp5 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea