- 原子性
事务是数据库的逻辑工作单位,事务中包括的诸操作要么全做,要么全不做。
- 一致性
事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
- 隔离性
一个事务的执行不能被其他事务干扰。
- 持续性
一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
在正常的web项目中,事务和DAO一直如影随行,所以有人认为配置事务和DAO的关系是密不可分,不能分离的。其实不然,DAO可以完全脱离容器独立存在。
<?xml version="1.0" encoding="UTF-8"?>applicationContext.xml
<beans xmlns=“http://www.springframework.org/schema/beans”
xmlns:p=“http://www.springframework.org/schema/p” 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:mvc=“http://www.springframework.org/schema/mvc”
xmlns:tx=“http://www.springframework.org/schema/tx”
xmlns:ehcache=“http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring”
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring
http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd">
<mvc:annotation-driven />
<context:component-scan base-package=“com.zhu” />
<bean id=“dataSource” class=“com.alibaba.druid.pool.DruidDataSource”
destroy-method=“close”
p:driverClassName=“com.mysql.jdbc.Driver”
p:username=“zhu”
p:password=“zhu” />
<bean id=“jdbcTemplate” class=“org.springframework.jdbc.core.JdbcTemplate”
p:dataSource-ref=“dataSource” />
zhu_test.sql
CREATE TABLE IF NOT EXISTS zhu_test (NAME VARCHAR(20),age INT(100)) ENGINE = INNODB;
测试类:
package com.zhu.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import com.alibaba.druid.pool.DruidDataSource;
@Service(“service1”)
public class UserJdbcWithoutTransManagerService {
@Autowired
private JdbcTemplate jdbcTemplate;
public void addScore(String userName,int toAdd){
String sql = “UPDATE zhu_test u SET u.age = u.age + ? WHERE name =?”;
jdbcTemplate.update(sql,toAdd,userName);
}
public static void main(String[] args) {
ApplicationContext ctx =
new ClassPathXmlApplicationContext(“file:src/main/resources/applicationContext.xml”);
UserJdbcWithoutTransManagerService service =
(UserJdbcWithoutTransManagerService)ctx.getBean(“service1”);
JdbcTemplate jdbcTemplate = (JdbcTemplate)ctx.getBean(“jdbcTemplate”);
DruidDataSource druidDataSource = (DruidDataSource)jdbcTemplate.getDataSource();
//①.检查数据源autoCommit的设置
System.out.println(“autoCommit:”+ druidDataSource.isDefaultAutoCommit());
//②.插入一条记录,初始分数为10
jdbcTemplate.execute(
“INSERT INTO zhu_test VALUES(‘tom’,10)”);
//③.调用工作在无事务环境下的服务类方法,将分数添加20分
service.addScore(“tom”,20);
//④.查看此时用户的分数
@SuppressWarnings(“deprecation”)
int score = jdbcTemplate.queryForInt(“SELECT age FROM zhu_test WHERE name =‘tom’”);
System.out.println(“score:”+score);
jdbcTemplate.execute(“DELETE FROM zhu_test WHERE name=‘tom’”);
}
}
运行结果:
applicationContext.xml中并没有配置事务,但是还是持久化到数据库中去了。DataSource默认设置是自动提交的,也就是说,在执行了CRUD之后,会马上持久化到数据库中。如果设置自动提交为false,那么在jdbcTemplate执行完之后并不会马上持久化到数据库中,除非手动提交。
虽说没有事务管理,程序依然可以进行数据的CRUD操作,但是没有事务管理,在数据安全同步方面会面临很大的挑战。栗子太多,不一一举例,看代码
我们故意提交一条错误的sql语句
package com.zhu.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import com.alibaba.druid.pool.DruidDataSource;
@Service(“service1”)
public class UserJdbcWithoutTransManagerService {
@Autowired
private JdbcTemplate jdbcTemplate;
public void addScore(String userName,int toAdd){
String sql = “UPDATE zhu_test u SET u.age = u.age + ? WHERE name =?”;
jdbcTemplate.update(sql,toAdd,userName);
}
public static void main(String[] args) {
ApplicationContext ctx =
new ClassPathXmlApplicationContext(“file:src/main/resources/applicationContext.xml”);
UserJdbcWithoutTransManagerService service =
(UserJdbcWithoutTransManagerService)ctx.getBean(“service1”);
JdbcTemplate jdbcTemplate = (JdbcTemplate)ctx.getBean(“jdbcTemplate”);
DruidDataSource druidDataSource = (DruidDataSource)jdbcTemplate.getDataSource();
//①.检查数据源autoCommit的设置
System.err.println(“autoCommit:”+ druidDataSource.isDefaultAutoCommit());
//②.插入一条记录,初始分数为10
jdbcTemplate.execute(
“INSERT INTO zhu_test VALUES(‘tom’,10)”);
//③.执行一条错误sql语句
jdbcTemplate.execute(
“INSERT INTO zhu_test VALUES(‘tom1’,10,00)”);
//④.调用工作在无事务环境下的服务类方法,将分数添加20分(不会执行)
service.addScore(“tom”,20);
}
}
清空数据,然后执行结果是:②成功插入数据tom 10 然后③错误的sql抛出异常 然后④更新操作也不会执行。
正常的逻辑是在同一方法或者类中执行一系列的CRUD操作,其中一条出出现问题会抛出异常,然后已经执行完的语句回滚到发生异常之前的状态。
这种情况在正常的开发环境是最基本的常识性错误,开发过程中一定要避免。
然后是配置事务。
applicationContext.xml文件中添加事务和模型视图的配置
package com.zhu.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class NoTMController {
//②.自动注入JdbcTemplate
@Autowired
private JdbcTemplate jdbcTemplate;
//③.通过Spring MVC注解映URL请求
@RequestMapping(“/logon”)
@ResponseBody
public String logon(String userName,String password){
String sql = “UPDATE zhu_test u SET u.age = u.age + ? WHERE name =?”;
if(isRightUser(userName,password)){
//执行更新操作(年龄加20)
jdbcTemplate.update(sql,20,“tom”);
//执行错误语句
jdbcTemplate.execute(
“INSERT INTO zhu_test VALUES(‘tom1’,10,00)”);
return “success”;
}else{
return “fail”;
}
}
private boolean isRightUser(String userName,String password){
//do sth…
return true;
}
}
总结
至此,文章终于到了尾声。总结一下,我们谈论了简历制作过程中需要注意的以下三个部分,并分别给出了一些建议:
- 技术能力:先写岗位所需能力,再写加分能力,不要写无关能力;
- 项目经历:只写明星项目,描述遵循 STAR 法则;
- 简历印象:简历遵循三大原则:清晰,简短,必要,要有的放矢,不要海投;
以及最后为大家准备的福利时间:简历模板+Java面试题+热门技术系列教程视频
(String userName,String password){
//do sth…
return true;
}
}
总结
至此,文章终于到了尾声。总结一下,我们谈论了简历制作过程中需要注意的以下三个部分,并分别给出了一些建议:
- 技术能力:先写岗位所需能力,再写加分能力,不要写无关能力;
- 项目经历:只写明星项目,描述遵循 STAR 法则;
- 简历印象:简历遵循三大原则:清晰,简短,必要,要有的放矢,不要海投;
以及最后为大家准备的福利时间:简历模板+Java面试题+热门技术系列教程视频
[外链图片转存中…(img-StHghd0I-1721068307617)]
[外链图片转存中…(img-9peGmD04-1721068307618)]
[外链图片转存中…(img-9oHbukwb-1721068307619)]