jdbcTemplate必须使用spring事务吗 否则不能提交
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jdbcTemplate必须使用spring事务吗 否则不能提交相关的知识,希望对你有一定的参考价值。
说明数据库执行了一条SQL语句,没有事务控就spring就不会提交,update不成功是正常的,你的那个异常在没有spring事务的控制下是不影响sql执行的。而且增删改本身就必须有事务,jdbc默认是自动提交事务,用了spring事务后由spring提交,配置了事务后,有没有事务对你都没影响,除非你不对数据库进行操作,如果不操作,你把方法名改了就好,如果要操作又想不用事务,那是不可能的。 参考技术A 如果启用事务,事务自动回滚。update不成功这个是正常的.
在spring中把update*的事务去掉或者把事务配置的代码全删掉,updateTestByid里去掉"
Spring之004: jdbcTemplate基本使用Spring实物控制
一、Spring JdbcTemplate基本使用:
1. JdbcTemplate概述:
它是spring框架中提供的一个对象, 是对原始繁琐的Jdbc API对象的简单封装. Spring框架提供了很多的操作模板类.
例如: 操作关系型数据的JdbcTemplate和HibernateTemplate, 操作nosql数据库的RedisTemplate, 操作消息队列的JMSTemplate等等;
2. JdbcTemplate开发步骤:
- 导入spring-jdbc和spring-tx坐标;
- 创建数据库表和实体;
- 创建JdbcTemplate对象;
- 执行数据库操作;
spring_jdbc/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project ...>
...
<properties>
...
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
</dependencies>
</project>
- 创建实体对象;
spring_jdbc/src/test/java/domain/Account.java
package domain;
public class Account {
private String name;
private double money;
public String getName() {
return name;
}
public double getMoney() {
return money;
}
public void setName(String name) {
this.name = name;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"name='" + name + '\\'' +
", money=" + money +
'}';
}
}
- 业务代码:
spring_jdbc/src/test/java/test/JdbcTemplateTest.java
package test;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
public class JdbcTemplateTest {
@Test
// 测试JdbcTempl
public void test1() throws Exception {
// 创建数据源对象
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test");
dataSource.setUser("root");
dataSource.setPassword("root123");
JdbcTemplate jdbcTemplate = new JdbcTemplate();
// 设置数据源对象
jdbcTemplate.setDataSource(dataSource);
// 执行操作
int row = jdbcTemplate.update("insert into account values(?, ?)", "tom", 5000);
System.out.println(row); // 1
}
}
3. Spring产生JdbcTemplate对象:
将JdbcTemplate的创建权交给Spring, 将数据源DataSource的创建权也交给Spring, 在Spring容器内部将数据源Database注入到JdbcTemplate模板对象中, 配置如下:
spring_jdbc/src/test/resources/applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/test"></property>
<property name="user" value="root"></property>
<property name="password" value="root123"></property>
</bean>
<!-- jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
测试代码:
spring_jdbc/src/test/java/test/JdbcTemplateTest.java
package test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.swing.*;
public class JdbcTemplateTest {
// 测试Spring获取JdbcTemplate
@Test
public void test2() {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate = app.getBean(JdbcTemplate.class);
// 执行操作
int row = jdbcTemplate.update("insert into account values(?, ?)", "jack", 1000);
System.out.println(row); // 1
}
}
4. 抽取数据库配置参数:
参考: 二、Spring相关配置, 数据源及注解开发/二、Spring配置数据源
5. JdbcTemplate的常用操作:
package test;
import domain.Account;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcTemplateCRUD {
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void testInsert() {
int row = jdbcTemplate.update("insert into account values(?, ?)", "zhangsan", 1000);
System.out.println(row);
}
@Test
public void testUpdate() {
int row = jdbcTemplate.update("update account set money=? where name=?", 10000, "tom");
System.out.println(row);
}
@Test
public void testDelete() {
int row = jdbcTemplate.update("delete from account where name=?", "tom");
System.out.println(row);
}
@Test
public void testQueryAll() {
List<Account> accountList = jdbcTemplate.query("select * from account", new BeanPropertyRowMapper<Account>(Account.class));
System.out.println(accountList);
}
@Test
public void testQueryOne() {
Account account = jdbcTemplate.queryForObject("select * from account where name=?",new BeanPropertyRowMapper<Account>(Account.class), "jack");
System.out.println(account); // Account{name='jack', money=50000.0}
}
@Test
public void testQueryCount() {
// 聚合查询
Long count = jdbcTemplate.queryForObject("select count(*) from account", Long.class);
System.out.println(count); // 4
}
}
二、Spring的事务控制:
1.编程式事务控制相关对象:
1.1 PlatformTransactionManager: 平台事务管理器
PlatformTransactionManager接口是Spring的事务管理器, 它里面提供了常用的操作事务的方法:
方法 | 说明 |
---|---|
TransactionStatus getTransaction(TransactionDefination defination) | 获取事务的状态信息 |
void commit(TransactioStatus status) | 提交事务 |
void rollback(TransactionStatus status) | 回滚事务 |
注意:
PlatformTransactioManager是接口类型, 不同的Dao层技术则有不同的实现类;
例如:
- Dao层技术是jdbc或mybatis时,
org.springframework.jdbc.datasource.DataSourceTransactionManager
;- Dao层技术是hibernta时:
org.springframework.orm.hibernate5.HibernateTransactionManager;
1.2 TransactionDefinition:
TransactionDefinition是事务的定义信息对象, 里面有如下方法:
方法 | 说明 |
---|---|
int getIsolationLevel() | 获取事务的隔离级别 |
int getPropogationBehavior() | 获取事务的传播行为 |
int getTimeout() | 获取超时时间 |
boolean isReadOnly() | 是否只读 |
1.2.1 事务的隔离级别:
设置隔离级别, 可以解决事务并发产生的问题, 如: 脏读, 不可重复读, 虚读(幻读)
- ISOLATION_DEFAULT: 默认
- ISOLATION_READ_UNCOMMITTED: 读未提交(不能解决)
- ISOLATION_READ_COMMITTED: 读已提交(解决脏读)
- ISOLATION_REPEATABLE_READ: 可重复读(解决不可重复读)
- ISOLATION_SERIALIZABLE: 串行化(全能解决, 但性能低, 相当于锁表)
1.2.2 事务的传播行为:
作用: 解决业务方法在调用业务方法时, 方法之间事务统一性的问题
- REQUIRED: 如果当前没有事务, 就新建一个事务, 如果已经存在一个事务中, 加入到这个事务中; 一般的选择(默认值);
- SUPPORTS: 支持当前事务, 如果当前没有事务, 就以非事务方式执行(没有事务);
- MANDATORY: 使用当前事务, 如果没有事务,就抛出异常;
- REQUERS_NEW: 新建事务, 如果当前在事务中, 就把当前事务挂起;
- NOT_SUPPORTED: 以非事务方式执行操作, 如果当前存在事务, 就把当前事务挂起;
- NEVER: 以非事务方式执行操作, 如果当前存在事务, 抛出异常;
- NESTED: 如果当前存在事务, 则在嵌套事务内执行; 如果当前没有事务, 则执行REQUIRED类似的操作;
- 超时时间: 默认值是-1, 没有超时限制; 如果有, 以秒为单位进行设置;
- 是否只读: 建议查询设置为只读;
1.3 TransactionStatus: 事务状态对象:
TransactionStatus接口提供的是事务具体的运行状态, 方法介绍如下:
方法 | 说明 |
---|---|
boolean hasSavepoint() | 是否存储回滚点 |
boolean isCompleted() | 事务是否完成 |
boolean isNewTransaction() | 是否是新事物 |
boolean isRollbackOnly() | 事务是否回滚 |
2. 基于Xml的声明式事务控制:
2.1 什么是声明式事务控制:
Spring的声明式事务就是采用声明的方式来处理事务
声明式事务处理的作用:
- 事务管理不侵入开发的组件;
- 在不需要事务的时候, 只要在配置文件上修改一下, 即可移去事务管服务;
Spring声明式事务控制底层就是AOP
以上是关于jdbcTemplate必须使用spring事务吗 否则不能提交的主要内容,如果未能解决你的问题,请参考以下文章
Spring之004: jdbcTemplate基本使用Spring实物控制
spring jdbctemplate 使用 AOP管理事务,但是无效,具体的配置文件如下: