當前位置:首頁 » 數據倉庫 » spring資料庫同步
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

spring資料庫同步

發布時間: 2022-07-08 00:07:05

『壹』 如何使用Spring配置非同步和同步事件發布

在Spring中使用非同步事件實現同步事務:

結合Scala+Spring,我們將採取一個很簡單的場景:下訂單,然後發送一封電子郵件。
編制一個服務:
@Service
class OrderService @Autowired() (orderDao: OrderDao, mailNotifier: OrderMailNotifier) {
@Transactional
def placeOrder(order: Order) {
orderDao save order //保存訂單
mailNotifier sendMail order //發送郵件
}
}
上面代碼是在保存訂單和發送郵件兩個同步執行,發送郵件需要連接郵件伺服器,比較耗時,拖延了整個性能,我們採取非同步發送電子郵件,利用Spring內置的自定義事件,與JMS或其他生產者 - 消費者類似。
case class OrderPlacedEvent(order: Order) extends ApplicationEvent

@Service
class OrderService @Autowired() (orderDao: OrderDao, eventPublisher: ApplicationEventPublisher) {

@Transactional
def placeOrder(order: Order) {
orderDao save order
eventPublisher publishEvent OrderPlacedEvent(order)
}

}
區別是繼承了ApplicationEvent 之前是直接用 OrderMailNotifier 直接發送,而現在我們使用ApplicationEventPublisher 發送發郵件事件了。
事件監聽者代碼如下:
@Service
class OrderMailNotifier extends ApplicationListener[OrderPlacedEvent] {

def onApplicationEvent(event: OrderPlacedEvent) {
//sending e-mail...
}

}
在監聽者方法中真正實現郵件發送。
但是Spring的ApplicationEvents是同步事件,意味著我們並沒有真正實現非同步,程序還會在這里堵塞,如果希望非同步,我們需要重新定義一個ApplicationEventMulticaster,實現類型和TaskExecutor:
@Bean
def applicationEventMulticaster() = {
val multicaster = new ()
multicaster.setTaskExecutor(taskExecutor())
multicaster
}

@Bean
def taskExecutor() = {
val pool = new ThreadPoolTaskExecutor()
pool.setMaxPoolSize(10)
pool.setCorePoolSize(10)
pool.setThreadNamePrefix("Spring-Async-")
pool
}
Spring通過使用TaskExecutor已經支持廣播事件了,對onApplicationEvent() 標注 @Async
@Async
def onApplicationEvent(event: OrderPlacedEvent) { //...
如果你希望使用@Async,可以編制自己的非同步執行器:
@Configuration
@EnableAsync
class ThreadingConfig extends AsyncConfigurer {
def getAsyncExecutor = taskExecutor()

@Bean
def taskExecutor() = {
val pool = new ThreadPoolTaskExecutor()
pool.setMaxPoolSize(10)
pool.setCorePoolSize(10)
pool.setThreadNamePrefix("Spring-Async-")
pool
}

}
@ EnableAsync是足夠了。,默認情況下,Spring使用SimpleAsyncTaskExecutor類創建新的線程。
以上所有設置暴露一個真正的問題。現在,我們雖然使用其他線程發送一個非同步消息處理。不幸的是,我們引入競爭條件。
開始事務
存儲order到資料庫
發送一個包裝order的消息
確認
非同步線程獲得OrderPlacedEvent並開始處理。現在的問題是,它發生(3)之後,還是(4)之前或者(4)之後?這有一個很大的區別!在前者的情況下,交易也尚未提交訂單所以不存在於資料庫中。另一方面,延遲載入可能已經在工作,致使訂單對象仍然然綁定在 PersistenceContext(預設我們使用JPA)。
解決辦法是使用 .,可以注冊很多監聽者 TransactionSynchronization,它對於事務的提交或回滾都有事件發送。
@Transactional
def placeOrder(order: Order) {
orderDao save order
afterCommit {
eventPublisher publishEvent OrderPlacedEvent(order)
}
}

private def afterCommit[T](fun: => T) {
.registerSynchronization(new {
override def afterCommit() {
fun
}
})
}
當前事務提交後 afterCommit()接受調用,可以安全地調用registerSynchronization()多次 - 監聽器存儲在Set並且本地保存到當前事務中,事務提交後消失。
我們將afterCommit方法單獨抽象成一個類,分離關注。
class (delegate: ApplicationEventPublisher)
extends ApplicationEventPublisher {

override def publishEvent(event: ApplicationEvent) {
if (.isActualTransactionActive) {
.registerSynchronization(
new {
override def afterCommit() {
delegate publishEvent event
}
})
}
else
delegate publishEvent event
}

}
是實現Spring的ApplicationEventPublisher。
我們要將這個新的實現告訴Spring替換掉舊的,用@Primary:
@Resource
val applicationContext: ApplicationContext = null

@Bean
@Primary
def () =
new (applicationContext)
再看看原來的訂單服務:
@Service
class OrderService @Autowired() (orderDao: OrderDao, eventPublisher:ApplicationEventPublisher) {
@Transactional
def placeOrder(order: Order) {
orderDao save order
eventPublisher publishEvent OrderPlacedEvent(order)
}
注意這里ApplicationEventPublisher已經是我們自己實現的,將被自動注入這個服務。
最後,要在真正訂單保存的業務代碼上放置事務:
def placeOrder(order: Order) {
storeOrder(order)
eventPublisher publishEvent OrderPlacedEvent(order)
}
@Transactional
def storeOrder(order: Order) = orderDao save order

『貳』 springboot之幾種同步,線程安全處理的方法

在一些公共資源的處理上,經常會出現對公共資源的爭奪使用許可權的問題,以及對資料庫處理時,容易出現線程安全的問題,比如對數據操作時的一致性,可見性等等。
這時候,為了避免這樣的問題,一般的處理方式是當某一個公共資源在被某一個線程調用時,把這個公共資源(即代碼塊)鎖住。
下面先大概介紹兩種簡單的同步方法:
註:同步是一種高開銷的操作,因此應該盡量減少同步的內容。
沒有必要同步整個方法,只使用synchronized代碼塊同步關鍵代碼即可。
1.同步方法
即有synchronized關鍵字修飾的方法。
由於java的每個對象都有一個內置鎖,當用此關鍵字修飾方法時,
內置鎖會保護整個方法。在調用該方法前,需要獲得內置鎖,否則就處於阻塞狀態。
代碼如:
public synchronized void demo(){}
註: synchronized關鍵字也可以修飾靜態方法,此時如果調用該靜態方法,將會鎖住整個類
2.同步代碼塊
即有synchronized關鍵字修飾的語句塊。
被該關鍵字修飾的語句塊會自動被加上內置鎖,從而實現同步
代碼如:
synchronized(object){
}

lock.lock(); try {
System.out.println("已鎖住"); for (int i=0;i<10;i++) { //放大代碼塊執行完成的時間,便於觀察
System.out.println(i); try {
System.out.println(Thread.currentThread().getName()+ "休眠5秒!");
Thread.sleep(5000);//放大代碼塊執行完成的時間,便於觀察
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}finally { lock.unlock();
System.out.println("解鎖");
}12345678910111213141516

當代碼塊被鎖住後,有其它的線程來調用被鎖住的線程時,必須先等待上一個線程使用完之後,釋放資源,才能繼續執行。
以上兩種方法很簡單,就不過多的寫了,但是這兩種方法在使用時,有以下幾個問題:
(1). 當公共資源被佔用時,其它線程必須等待資源被釋放後才能執行,這種場景適用於對資料庫的操作,保證其數據的原子性。當被搶占的資源是即時的公共資源,只有在某一時刻搶到才有意義,比如說在公共場所對空調的控制,大家都要爭奪對空調的控制權,但如果是用上述的方法,對空調的控制會按照發出請求的時間,依次執行,那就沒有意義了。所以這種場景適合只執行最先搶到資源的線程,在資源被佔用時,殺死其它的請求線程。這種情況用以下的方法實現
3. Semaphore並發包
Semaphore是基於計數的信號量,它可以設定一個資源的總數量,基於這個總數量,多線程競爭獲取許可信號,做自己的申請後歸還,超過總數量後,線程申請許可,信號將會被阻塞。等到有資源時,繼續執行。
下面在springboot中實現:

@Contorller public class Controller(){
Semaphore semaphore=new Semaphore(1); //定義資源的總數量
@GetMapping("/userInfo/request")
@ResponseBody public String Resquest(){ int availablePermits=semaphore.availablePermits();//可用資源數
if(availablePermits>0){
System.out.println("搶到資源");
}else{
System.out.println("資源已被佔用,稍後再試"); return "Resource is busy!";
} try {
semaphore.acquire(1); //請求佔用一個資源
System.out.println("資源正在被使用");
Thread.sleep(30000);//放大資源佔用時間,便於觀察
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
semaphore.release(1);//釋放一個資源
} return "Success";
}

}

當只有一個資源請求時,效果如下:

大致的思路和框架就是這樣,可根據自己的需要進行修改。

『叄』 關於Spring配置資料庫

在src下創建.properties。
jdbc.driverClass=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@*.*.*.*:1521:oel1245
jdbc.username=userName
jdbc.password=password
jdbc.maxActive=30
jdbc.maxIdle=30
jdbc.maxWait=3000
然後在applicationContext.xml文件中載入這個文件,
然後再配置DataSource就OK了

如果是其他資料庫的話請更改driverClass和url

也可以直接在applicationContext中配置行相應的值,而不需要.properties

『肆』 如何利用Spring實現資料庫讀寫分離

讀寫分離是為了減少資料庫的負荷,當用戶高並發訪問時,絕大部分都是用戶查詢,少部分用戶是寫入到資料庫的。這些我們把資料庫拆分成主從兩個資料庫,主資料庫用高性能

伺服器承載高並發的用戶訪問並加redis緩存。在這里我不講mysql的主從同步配置,大家可以去查下資料,我接下來重點講怎麼動態的給每個sql注入數據源。

『伍』 如何用spring 調用資料庫連接使用jdbc

一 ,使用spring的jdbc
1.在myeclipse添加spring jar包,
添加Spring2.5 Core/AOP/ JDBC Library
2.在applicationContext.xml中,配置jdbc bean:

『陸』 Spring連接資料庫的幾種常用方法

資料庫是按照數據結構來組織、存儲和管理數據的倉庫,它產生於距今六十多年前,隨著信息技術和市場的發展,特別是二十世紀九十年代以後,數據管理不再僅僅是存儲和管理數據,而轉變成用戶所需要的各種數據管理的方式。資料庫有很多種類型,從最簡單的存儲有各種數據的表格到能夠進行海量數據存儲的大型資料庫系統都在各個方面得到了廣泛的應用。在信息化社會,充分有效地管理和利用各類信息資源,是進行科學研究和決策管理的前提條件。資料庫技術是管理信息系統、辦公自動化系統、決策支持系統等各類信息系統的核心部分,是進行科學研究和決策管理的重要技術手段。資料庫是一個單位或是一個應用領域的通用數據處理系統,它存儲的是屬於企業和事業部門、團體和個人的有關數據的集合。資料庫中的數據是從全局觀點出發建立的,按一定的數據模型進行組織、描述和存儲。其結構基於數據間的自然聯系,從而可提供一切必要的存取路徑,且數據不再針對某一應用,而是面向全組織,具有整體的結構化特徵。資料庫中的數據是為眾多用戶所共享其信息而建立的,已經擺脫了具體程序的限制和制約。不同的用戶可以按各自的用法使用資料庫中的數據;多個用戶可以同時共享資料庫中的數據資源,即不同的用戶可以同時存取資料庫中的同一個數據。數據共享性不僅滿足了各用戶對信息內容的要求,同時也滿足了各用戶之間信息通信的要求。

『柒』 spring整合資料庫連接的幾種方式

1.解決方案:
property name="<.commons; value=" value="close".properties文件
2.配置多個資料庫:
jdbc;minEvictableIdleTimeMillis"driverClassName".maxActive}" /
password}".url}"${jdbc;>.driver;3600000"maxActive";>${jdbc.driver}"
/username"${dbcp;
</ value=".dbcp;url".BasicDataSource"
< value="bean id=".username}"
< value="
<>password"${dbcp;org.;dataSource"false" /
<property name=" destroy-method="3600000"
application;property name=" class=",property name="
< value=">.apache; value=" /property name=">
<${jdbc;property name="property name=">.;

『捌』 spring連接資料庫的技術理論是什麼

Spring工作原理
Spring 已經用過一段時間了,感覺Spring是個很不錯的框架。內部最核心的就是IOC了,
動態注入,讓一個對象的創建不用new了,可以自動的生產,這其實就是利用java里的反射
反射其實就是在運行時動態的去創建、調用對象,Spring就是在運行時,跟xml Spring的配置
文件來動態的創建對象,和調用對象里的方法的 。
Spring還有一個核心就是AOP這個就是面向切面編程,可以為某一類對象 進行監督和控制(也就是
在調用這類對象的具體方法的前後去調用你指定的 模塊)從而達到對一個模塊擴充的功能。這些都是通過
配置類達到的。
Spring目的:就是讓對象與對象(模塊與模塊)之間的關系沒有通過代碼來關聯,都是通過配置類說明
管理的(Spring根據這些配置 內部通過反射去動態的組裝對象)
要記住:Spring是一個容器,凡是在容器里的對象才會有Spring所提供的這些服務和功能。
Spring里用的最經典的一個設計模式就是:模板方法模式。(這里我都不介紹了,是一個很常用的設計模式)
Spring里的配置是很多的,很難都記住,但是Spring里的精華也無非就是以上的兩點,把以上兩點跟理解了
也就基本上掌握了Spring.

『玖』 spring+mybatis 多資料庫事務管理:一個方法裡面能同時對兩個資料庫的數據進行操作

  1. 定義兩個DAO分別使用不同的數據源,ADAO連接A資料庫,BDAO連接B資料庫

  2. 定義一個Service類,加上Spring註解@Transactional,表示進行事務管理。

    將ADAO和BDAO注入到Service類裡面。

    在service類裡面創建一個方法,方法里調用ADAO的方法插入數據到A資料庫的user表,然後調用BDAO的方法插入數據到B資料庫的user表