Spring之路(38)–基於PlatformTransactionM
程式設計式事務管理
所謂程式設計式事務管理
,就是使用普通的程式程式碼來管理事務,像上一篇原生JDBC事務實現就是程式設計式的。
與程式設計式事務相對應的就是宣告式事務管理
,透過對方法或類新增註解的方式,宣告該方法或類開啟事務。很明顯宣告式事務程式碼量更少更加簡單,更加高階,平時用的也更多,但是我們還是從最基礎的程式設計式事務開始講起。
具體實現
PlatformTransactionManager是Spring封裝好介面,其使用方法跟原生JDBC幾乎一樣,將其生成bean納入Spring容器管理後呼叫即可。
注意PlatformTransactionManager是介面,具體操作需要呼叫其具體實現類,一般透過資料來源訪問資料庫的可以使用DataSourceTransactionManager。注意還有一些其他的PlatformTransactionManager具體實現類,到目前為止我們都是使用JDBC資料來源訪問資料庫的,所以瞭解DataSourceTransactionManager已足夠。
首先定義配置類:
package org.maoge.plantformtran;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import com.alibaba.druid.pool.DruidDataSource;
/**
* Spring配置類
*/
@Configuration
public class SpringConfig {
/**
* 定義資料來源bean
*/
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/myblog?useUnicode=true&characterEncoding=utf-8");
dataSource.setUsername("root");
dataSource.setPassword("Easy@0122");
return dataSource;
}
/**
* 定義事務管理bean
*/
@Bean
public PlatformTransactionManager transactionManager() {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource());// 注入dataSource
return transactionManager;
}
/**
* 配置namedParameterJdbcTemplate元件
*/
@Bean
public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(dataSource());// 注入dataSource
return template;
}
/**
* 為BlogDao註冊bean
*/
@Bean
public BlogDao blogDao() {
BlogDao blogDao = new BlogDao();
blogDao.setNamedTemplate(namedParameterJdbcTemplate());// 注入namedParameterJdbcTemplate
return blogDao;
}
}
然後定義資料物件Do及資料操作類Dao
package org.maoge.nameddemo;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
/**
* @theme DAO--部落格
* @author maoge
* @date 2020-01-29
*/
public class BlogDao {
public NamedParameterJdbcTemplate getNamedTemplate() {
return namedTemplate;
}
public void setNamedTemplate(NamedParameterJdbcTemplate namedTemplate) {
this.namedTemplate = namedTemplate;
}
private NamedParameterJdbcTemplate namedTemplate;
/**
* 新增
*/
public void insert(BlogDo blog) {
Map<String, Object> map = new HashMap<>();
map.put("author", blog.getAuthor());
map.put("content", blog.getContent());
map.put("title", blog.getTitle());
// 注意使用:xxx佔位
namedTemplate.update("insert into blog(author,content,title)values(:author,:content,:title)", map);
}
/**
* 刪除
*/
public void delete(Long id) {
Map<String, Object> map = new HashMap<>();
map.put("id", id);
namedTemplate.update("delete from blog where id =:id", map);
}
/**
* 更新
*/
public void update(BlogDo blog) {
Map<String, Object> map = new HashMap<>();
map.put("author", blog.getAuthor());
map.put("content", blog.getContent());
map.put("title", blog.getTitle());
map.put("id", blog.getId());
namedTemplate.update("update blog set author=:author,content=:content,title=:title where id=:id", map);
}
/**
* 按id查詢
*/
public BlogDo getById(Long id) {
Map<String, Object> map = new HashMap<>();
map.put("id", id);
return namedTemplate.queryForObject("select * from blog where id=:id", map, new RowMapper<BlogDo>() {
@Override
public BlogDo mapRow(ResultSet rs, int rowNum) throws SQLException {
BlogDo blog = new BlogDo();
blog.setAuthor(rs.getString("author"));
blog.setContent(rs.getString("content"));
blog.setId(rs.getLong("id"));
blog.setTitle(rs.getString("title"));
return blog;
}
});
}
/**
* 查詢列表
*/
public List<BlogDo> getList() {
return namedTemplate.query("select * from blog", new RowMapper<BlogDo>() {
@Override
public BlogDo mapRow(ResultSet rs, int rowNum) throws SQLException {
BlogDo blog = new BlogDo();
blog.setAuthor(rs.getString("author"));
blog.setContent(rs.getString("content"));
blog.setId(rs.getLong("id"));
blog.setTitle(rs.getString("title"));
return blog;
}
});
}
}
package org.maoge.nameddemo;
/**
* @theme 資料物件--部落格
* @author maoge
* @date 2020-01-27
*/
public class BlogDo {
private Long id;
private String title;
private String author;
private String content;
// 省略get get
}
最後編寫測試程式碼:
package org.maoge.plantformtran;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
public class Main {
public static void main(String[] args) {
// 獲取容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
// 容器中獲取事務管理元件
PlatformTransactionManager transactionManager = (PlatformTransactionManager) context
.getBean("transactionManager");
// 開始事務
TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(transactionDefinition);
// 容器中獲取資料庫操作元件
BlogDao blogDao = (BlogDao) context.getBean("blogDao");
try {
// 執行資料庫操作
BlogDo blog = new BlogDo();
blog.setContent("測試");
blogDao.insert(blog);
// 模擬異常
int a = 1 / 0;
blogDao.insert(blog);
// 提交事務
transactionManager.commit(status);
} catch (Exception e) {
// 發生異常則回滾
transactionManager.rollback(status);
e.printStackTrace();
}
}
}
由於中間執行int a = 1 / 0;
發生異常,導致事務回滾,所以實際上一條記錄都沒插入成功。
總結
使用基於PlatformTransactionManager的程式設計式事務管理,跟原生JDBC相比並未節省什麼程式碼,提供了封裝事務的元件,這種方式基本沒人使用,僅作為了解吧。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3244/viewspace-2824858/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Python學習之路38-動態建立屬性Python
- OceanBase學習之路38|如何合併資源池?
- 基於Spring Boot傳送 mailSpring BootAI
- Spring基於XML方式的使用SpringXML
- 基於Maven的Spring整合CXFMavenSpring
- 基於Spring例子的JPetStore分析Spring
- 基於 LNMP 的 Nginx 百萬併發之路 (三)基於域名的虛擬主機LNMPNginx
- 基於Spring Batch的Spring Boot的教程 - BaeldungBATSpring Boot
- Spring框架自學之路Spring框架
- Spring自學之路---AOPSpring
- 滴滴基於Go語言的DevOps重塑之路Godev
- Spring7:基於註解的Spring MVC(下篇)SpringMVC
- Spring6:基於註解的Spring MVC(上篇)SpringMVC
- 基於spring實現事件驅動Spring事件
- spring boot基於Java的容器配置Spring BootJava
- Spring基於註解的IoC配置Spring
- Spring基於註解的aop配置Spring
- 基於Spring Cloud的微服務落地SpringCloud微服務
- spring基於java配置DispatcherServlet和viewSpringJavaServletView
- Spring(5、基於註解的事物)Spring
- Bootstrap系列 -- 38. 基礎導航條boot
- 基於 LNMP 的 Nginx 百萬併發之路 (四)熱部署LNMPNginx熱部署
- Spring7——開發基於註解形式的springSpring
- Spring Aop基於註解的實現Spring
- Spring中基於XML方式的AOP操作SpringXML
- 基於Spring Cloud搭建分散式配置中心SpringCloud分散式
- 基於Spring Integration和Apache Camel的SEDASpringApache
- 基於Spring的Restful介面生成工具SpringREST
- 基於註解的 Spring MVC詳解SpringMVC
- Spring基於註解的AOP測試Spring
- Spring AOP基於xml的方式實現SpringXML
- spring上 -基於Xml配置bean筆記SpringXMLBean筆記
- 基於 Istio 的灰度釋出架構方案實踐之路架構
- Spring / Spring boot 基於註解非同步程式設計@AsyncSpring Boot非同步程式設計
- 基於Spring Boot和Spring Cloud實現微服務架構Spring BootCloud微服務架構
- Spring MVC 到 Spring Boot 的簡化之路MVCSpring Boot
- Spring中基於註解方式的AOP操作Spring
- 基於Spring的流量拷貝框架實現Spring框架