真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

java分布式事務(wù)代碼 java分布式事務(wù)解決方案

java程序員在面試中被問(wèn)到如何配置多數(shù)據(jù)源以及如何配置多數(shù)據(jù)源下的分布式事務(wù),該怎么回答?看清再做答

你好,我來(lái)先回答你的第一個(gè)問(wèn)題:

成都創(chuàng)新互聯(lián)專(zhuān)注于洛陽(yáng)網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供洛陽(yáng)營(yíng)銷(xiāo)型網(wǎng)站建設(shè),洛陽(yáng)網(wǎng)站制作、洛陽(yáng)網(wǎng)頁(yè)設(shè)計(jì)、洛陽(yáng)網(wǎng)站官網(wǎng)定制、成都微信小程序服務(wù),打造洛陽(yáng)網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供洛陽(yáng)網(wǎng)站排名全網(wǎng)營(yíng)銷(xiāo)落地服務(wù)。

通常多數(shù)據(jù)源,在spring中配置如下,如果你想切換環(huán)境ENV 的值,在property中

bean id="placeholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"

property name="ignoreResourceNotFound" value="true"/property

property name="ignoreUnresolvablePlaceholders" value="true"/property

property name="nullValue" value="NULL"/property

property name="locations"

list

valuejdbc.properties/value

/list

/property

/bean

bean id="dataSource" class="com.spring.dao.JDBCConfig"

property name="driverClassName" value="${${Env}.jdbc.driverClassName}"/property

property name="url" value="${${Env}.jdbc.url}"/property

property name="username" value="${${Env}.jdbc.username1}"/property

property name="password" value="${${Env}.jdbc.password}"/property

/bean

jdbc.properties

*****************************

Env=PROD

jdbc.driverClassName=${${Env}.jdbc.driverClassName}

jdbc.url=${${Env}.jdbc.url}

jdbc.username=${${Env}.jdbc.username}

jdbc.password=${${Env}.jdbc.password}

######### JDBC Configuration for DEV Environment ###############

DEV.jdbc.driverClassName=com.mysql.jdbc.Driver

DEV.jdbc.url=jdbc:mysql://localhost:3306/devportal

DEV.jdbc.username=DEVuser

DEV.jdbc.password=DEVpwd

######### JDBC Configuration for UAT Environment ############

UAT.jdbc.driverClassName=com.mysql.jdbc.Driver

UAT.jdbc.url=jdbc:mysql://localhost:3306/UATportal

UAT.jdbc.username=UATuser

UAT.jdbc.password=UATpwd

########## JDBC Configuration for PROD Environment ############

PROD.jdbc.driverClassName=com.mysql.jdbc.Driver

PROD.jdbc.url=jdbc:mysql://localhost:3306/portal

PROD.jdbc.username=root

PROD.jdbc.password=admin,

我這里有三套環(huán)境,分別是DEV,UAT和PROD,這種方式可以靈活切換的。

我再回答你的第二個(gè)問(wèn)題:

還請(qǐng)你去這里看下,很詳細(xì),不過(guò)是英文的哦

java的框架spring如何配置分布式事務(wù)?

分布式事務(wù)是指操作多個(gè)數(shù)據(jù)庫(kù)之間的事務(wù),在tomcat下是沒(méi)有分布式事務(wù)的,可以借助于第三方Jotm和Automikos實(shí)現(xiàn),下面就寫(xiě)一個(gè)使用Jotm實(shí)現(xiàn)分布事務(wù)的例子,如有不足,請(qǐng)各位大大指點(diǎn):

Dao及實(shí)現(xiàn),先寫(xiě)出一個(gè)interface再去實(shí)現(xiàn)他,可能有些人覺(jué)得直接寫(xiě)實(shí)現(xiàn)類(lèi)多好,但我還是建議為了結(jié)構(gòu)清晰,增強(qiáng)代碼的可讀性,可維護(hù)性還是先寫(xiě)接口再去實(shí)現(xiàn)的好:

先寫(xiě)一個(gè)interface,定義要實(shí)現(xiàn)的方法:

實(shí)現(xiàn)接口,傳入一個(gè)String ds來(lái)判斷調(diào)用哪個(gè)JdbcTemplate:

service及實(shí)現(xiàn):

還是接口與他的實(shí)現(xiàn):

持久化的操作:

applicationContext.xml

基本的spring配置以及Jotm bean;

JTA事務(wù)管理器,數(shù)據(jù)源datasourceA和datasourceB配置:

事務(wù)切面配置aop,通知配置以及dao,service配置:

單元測(cè)試,在實(shí)際項(xiàng)目中就是寫(xiě)一個(gè)controller:

Java分布式系統(tǒng)處理分布式事務(wù)有哪些經(jīng)典解決方

當(dāng)我們?cè)谏a(chǎn)線上用一臺(tái)服務(wù)器來(lái)提供數(shù)據(jù)服務(wù)的時(shí)候,我會(huì)遇到如下的兩個(gè)問(wèn)題:

1)一臺(tái)服務(wù)器的性能不足以提供足夠的能力服務(wù)于所有的網(wǎng)絡(luò)請(qǐng)求。

2)我們總是害怕我們的這臺(tái)服務(wù)器停機(jī),造成服務(wù)不可用或是數(shù)據(jù)丟失。

于是我們不得不對(duì)我們的服務(wù)器進(jìn)行擴(kuò)展,加入更多的機(jī)器來(lái)分擔(dān)性能上的問(wèn)題,以及來(lái)解決單點(diǎn)故障問(wèn)題。 通常,我們會(huì)通過(guò)兩種手段來(lái)擴(kuò)展我們的數(shù)據(jù)服務(wù):

1)數(shù)據(jù)分區(qū):就是把數(shù)據(jù)分塊放在不同的服務(wù)器上(如:uid % 16,一致性哈希等)。

2)數(shù)據(jù)鏡像:讓所有的服務(wù)器都有相同的數(shù)據(jù),提供相當(dāng)?shù)姆?wù)。

對(duì)于第一種情況,我們無(wú)法解決數(shù)據(jù)丟失的問(wèn)題,單臺(tái)服務(wù)器出問(wèn)題時(shí),會(huì)有部分?jǐn)?shù)據(jù)丟失。所以,數(shù)據(jù)服務(wù)的高可用性只能通過(guò)第二種方法來(lái)完成——數(shù)據(jù)的冗余存儲(chǔ)(一般工業(yè)界認(rèn)為比較安全的備份數(shù)應(yīng)該是3份,如:Hadoop和Dynamo)。 但是,加入更多的機(jī)器,會(huì)讓我們的數(shù)據(jù)服務(wù)變得很復(fù)雜,尤其是跨服務(wù)器的事務(wù)處理,也就是跨服務(wù)器的數(shù)據(jù)一致性。這個(gè)是一個(gè)很難的問(wèn)題。 讓我們用最經(jīng)典的Use Case:“A帳號(hào)向B帳號(hào)匯錢(qián)”來(lái)說(shuō)明一下,熟悉RDBMS事務(wù)的都知道從帳號(hào)A到帳號(hào)B需要6個(gè)操作:

從A帳號(hào)中把余額讀出來(lái)。

對(duì)A帳號(hào)做減法操作。

把結(jié)果寫(xiě)回A帳號(hào)中。

從B帳號(hào)中把余額讀出來(lái)。

對(duì)B帳號(hào)做加法操作。

把結(jié)果寫(xiě)回B帳號(hào)中。

為了數(shù)據(jù)的一致性,這6件事,要么都成功做完,要么都不成功,而且這個(gè)操作的過(guò)程中,對(duì)A、B帳號(hào)的其它訪問(wèn)必需鎖死,所謂鎖死就是要排除其它的讀寫(xiě)操作,不然會(huì)有臟數(shù)據(jù)的問(wèn)題,這就是事務(wù)。那么,我們?cè)诩尤肓烁嗟臋C(jī)器后,這個(gè)事情會(huì)變得復(fù)雜起來(lái):

1)在數(shù)據(jù)分區(qū)的方案中:如果A帳號(hào)和B帳號(hào)的數(shù)據(jù)不在同一臺(tái)服務(wù)器上怎么辦?我們需要一個(gè)跨機(jī)器的事務(wù)處理。也就是說(shuō),如果A的扣錢(qián)成功了,但B的加錢(qián)不成功,我們還要把A的操作給回滾回去。這在跨機(jī)器的情況下,就變得比較復(fù)雜了。

2)在數(shù)據(jù)鏡像的方案中:A帳號(hào)和B帳號(hào)間的匯款是可以在一臺(tái)機(jī)器上完成的,但是別忘了我們有多臺(tái)機(jī)器存在A帳號(hào)和B帳號(hào)的副本。如果對(duì)A帳號(hào)的匯錢(qián)有兩個(gè)并發(fā)操作(要匯給B和C),這兩個(gè)操作發(fā)生在不同的兩臺(tái)服務(wù)器上怎么辦?也就是說(shuō),在數(shù)據(jù)鏡像中,在不同的服務(wù)器上對(duì)同一個(gè)數(shù)據(jù)的寫(xiě)操作怎么保證其一致性,保證數(shù)據(jù)不沖突?

同時(shí),我們還要考慮性能的因素,如果不考慮性能的話(huà),事務(wù)得到保證并不困難,系統(tǒng)慢一點(diǎn)就行了。除了考慮性能外,我們還要考慮可用性,也就是說(shuō),一臺(tái)機(jī)器沒(méi)了,數(shù)據(jù)不丟失,服務(wù)可由別的機(jī)器繼續(xù)提供。 于是,我們需要重點(diǎn)考慮下面的這么幾個(gè)情況:

1)容災(zāi):數(shù)據(jù)不丟、節(jié)點(diǎn)的Failover

2)數(shù)據(jù)的一致性:事務(wù)處理

3)性能:吞吐量 、 響應(yīng)時(shí)間

前面說(shuō)過(guò),要解決數(shù)據(jù)不丟,只能通過(guò)數(shù)據(jù)冗余的方法,就算是數(shù)據(jù)分區(qū),每個(gè)區(qū)也需要進(jìn)行數(shù)據(jù)冗余處理。這就是數(shù)據(jù)副本:當(dāng)出現(xiàn)某個(gè)節(jié)點(diǎn)的數(shù)據(jù)丟失時(shí)可以從副本讀到,數(shù)據(jù)副本是分布式系統(tǒng)解決數(shù)據(jù)丟失異常的唯一手段。所以,在這篇文章中,簡(jiǎn)單起見(jiàn),我們只討論在數(shù)據(jù)冗余情況下考慮數(shù)據(jù)的一致性和性能的問(wèn)題。簡(jiǎn)單說(shuō)來(lái):

1)要想讓數(shù)據(jù)有高可用性,就得寫(xiě)多份數(shù)據(jù)。

2)寫(xiě)多份的問(wèn)題會(huì)導(dǎo)致數(shù)據(jù)一致性的問(wèn)題。

3)數(shù)據(jù)一致性的問(wèn)題又會(huì)引發(fā)性能問(wèn)題

這就是軟件開(kāi)發(fā),按下了葫蘆起了瓢。

一致性模型

說(shuō)起數(shù)據(jù)一致性來(lái)說(shuō),簡(jiǎn)單說(shuō)有三種類(lèi)型(當(dāng)然,如果細(xì)分的話(huà),還有很多一致性模型,如:順序一致性,F(xiàn)IFO一致性,會(huì)話(huà)一致性,單讀一致性,單寫(xiě)一致性,但為了本文的簡(jiǎn)單易讀,我只說(shuō)下面三種):

1)Weak 弱一致性:當(dāng)你寫(xiě)入一個(gè)新值后,讀操作在數(shù)據(jù)副本上可能讀出來(lái),也可能讀不出來(lái)。比如:某些cache系統(tǒng),網(wǎng)絡(luò)游戲其它玩家的數(shù)據(jù)和你沒(méi)什么關(guān)系,VOIP這樣的系統(tǒng),或是百度搜索引擎(呵呵)。

2)Eventually 最終一致性:當(dāng)你寫(xiě)入一個(gè)新值后,有可能讀不出來(lái),但在某個(gè)時(shí)間窗口之后保證最終能讀出來(lái)。比如:DNS,電子郵件、Amazon S3,Google搜索引擎這樣的系統(tǒng)。

3)Strong 強(qiáng)一致性:新的數(shù)據(jù)一旦寫(xiě)入,在任意副本任意時(shí)刻都能讀到新值。比如:文件系統(tǒng),RDBMS,Azure Table都是強(qiáng)一致性的。

從這三種一致型的模型上來(lái)說(shuō),我們可以看到,Weak和Eventually一般來(lái)說(shuō)是異步冗余的,而Strong一般來(lái)說(shuō)是同步冗余的,異步的通常意味著更好的性能,但也意味著更復(fù)雜的狀態(tài)控制。同步意味著簡(jiǎn)單,但也意味著性能下降。 好,讓我們由淺入深,一步一步地來(lái)看有哪些技術(shù):

Master-Slave

首先是Master-Slave結(jié)構(gòu),對(duì)于這種加構(gòu),Slave一般是Master的備份。在這樣的系統(tǒng)中,一般是如下設(shè)計(jì)的:

1)讀寫(xiě)請(qǐng)求都由Master負(fù)責(zé)。

2)寫(xiě)請(qǐng)求寫(xiě)到Master上后,由Master同步到Slave上。

從Master同步到Slave上,你可以使用異步,也可以使用同步,可以使用Master來(lái)push,也可以使用Slave來(lái)pull。 通常來(lái)說(shuō)是Slave來(lái)周期性的pull,所以,是最終一致性。這個(gè)設(shè)計(jì)的問(wèn)題是,如果Master在pull周期內(nèi)垮掉了,那么會(huì)導(dǎo)致這個(gè)時(shí)間片內(nèi)的數(shù)據(jù)丟失。如果你不想讓數(shù)據(jù)丟掉,Slave只能成為Read-Only的方式等Master恢復(fù)。

當(dāng)然,如果你可以容忍數(shù)據(jù)丟掉的話(huà),你可以馬上讓Slave代替Master工作(對(duì)于只負(fù)責(zé)計(jì)算的節(jié)點(diǎn)來(lái)說(shuō),沒(méi)有數(shù)據(jù)一致性和數(shù)據(jù)丟失的問(wèn)題,Master-Slave的方式就可以解決單點(diǎn)問(wèn)題了) 當(dāng)然,Master Slave也可以是強(qiáng)一致性的, 比如:當(dāng)我們寫(xiě)Master的時(shí)候,Master負(fù)責(zé)先寫(xiě)自己,等成功后,再寫(xiě)Slave,兩者都成功后返回成功,整個(gè)過(guò)程是同步的,如果寫(xiě)Slave失敗了,那么兩種方法,一種是標(biāo)記Slave不可用報(bào)錯(cuò)并繼續(xù)服務(wù)(等Slave恢復(fù)后同步Master的數(shù)據(jù),可以有多個(gè)Slave,這樣少一個(gè),還有備份,就像前面說(shuō)的寫(xiě)三份那樣),另一種是回滾自己并返回寫(xiě)失敗。(注:一般不先寫(xiě)Slave,因?yàn)槿绻麑?xiě)Master自己失敗后,還要回滾Slave,此時(shí)如果回滾Slave失敗,就得手工訂正數(shù)據(jù)了)你可以看到,如果Master-Slave需要做成強(qiáng)一致性有多復(fù)雜。

Master-Master

Master-Master,又叫Multi-master,是指一個(gè)系統(tǒng)存在兩個(gè)或多個(gè)Master,每個(gè)Master都提供read-write服務(wù)。這個(gè)模型是Master-Slave的加強(qiáng)版,數(shù)據(jù)間同步一般是通過(guò)Master間的異步完成,所以是最終一致性。 Master-Master的好處是,一臺(tái)Master掛了,別的Master可以正常做讀寫(xiě)服務(wù),他和Master-Slave一樣,當(dāng)數(shù)據(jù)沒(méi)有被復(fù)制到別的Master上時(shí),數(shù)據(jù)會(huì)丟失。很多數(shù)據(jù)庫(kù)都支持Master-Master的Replication的機(jī)制。

另外,如果多個(gè)Master對(duì)同一個(gè)數(shù)據(jù)進(jìn)行修改的時(shí)候,這個(gè)模型的惡夢(mèng)就出現(xiàn)了——對(duì)數(shù)據(jù)間的沖突合并,這并不是一件容易的事情??纯碊ynamo的Vector Clock的設(shè)計(jì)(記錄數(shù)據(jù)的版本號(hào)和修改者)就知道這個(gè)事并不那么簡(jiǎn)單,而且Dynamo對(duì)數(shù)據(jù)沖突這個(gè)事是交給用戶(hù)自己搞的。就像我們的SVN源碼沖突一樣,對(duì)于同一行代碼的沖突,只能交給開(kāi)發(fā)者自己來(lái)處理。(在本文后后面會(huì)討論一下Dynamo的Vector Clock)

Two/Three Phase Commit

這個(gè)協(xié)議的縮寫(xiě)又叫2PC,中文叫兩階段提交。在分布式系統(tǒng)中,每個(gè)節(jié)點(diǎn)雖然可以知曉自己的操作時(shí)成功或者失敗,卻無(wú)法知道其他節(jié)點(diǎn)的操作的成功或失敗。當(dāng)一個(gè)事務(wù)跨越多個(gè)節(jié)點(diǎn)時(shí),為了保持事務(wù)的ACID特性,需要引入一個(gè)作為協(xié)調(diào)者的組件來(lái)統(tǒng)一掌控所有節(jié)點(diǎn)(稱(chēng)作參與者)的操作結(jié)果并最終指示這些節(jié)點(diǎn)是否要把操作結(jié)果進(jìn)行真正的提交(比如將更新后的數(shù)據(jù)寫(xiě)入磁盤(pán)等等)。

如何用java開(kāi)啟mysql事務(wù),要求詳細(xì)

看你是什么事務(wù),jdbc事務(wù),還是分布式事務(wù),還是容器事務(wù)

1,編程式事務(wù)管理(jdbc的事務(wù)是綁定在connection上的)

Connection conn = null;

try

{

Class.forName("com.mysql.jdbc.Driver");

conn = DriverManager.getConnection("jdbc:oracle:thin:@host:1521:SID","username","password");

conn.setAutoCommit(false); //取消自動(dòng)提交

PreparedStatement ps = conn.prepareCall("update something");

ResultSet rs = ps.executeQuery();

conn.commit(); //手動(dòng)提交

}

catch (Exception e)

{

conn.rollback();

e.printStackTrace();

}

finally

{

conn.close();

}

2,聲明式事務(wù)

先在工程的application.xml配置文件中添加如下代碼,開(kāi)啟事務(wù)

!-- 聲明式事務(wù)控制配置 --

tx:annotation-driven transaction-manager="txManager"/

bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"

property name="datasource" ref="bassDataSource"/property

/bean

然后在你需要開(kāi)啟事務(wù)的接口前面添加注解

@Transactional(rollbackFor = IOException.class)

public void add(String name) throws IOException

{

System.out.println("可以再類(lèi)里和方法里面添加事務(wù)注解0~0");

throw new IOException();

}

直接調(diào)用接口方法就好

分布式事務(wù)處理(mysql貌似在5.X之后才支持) 的話(huà),

1.可以直接使用spring+atomikos框架進(jìn)行管理

參考:

就不貼測(cè)試代碼了,自己看著配置吧

2,使用JTA(Java Transaction API)進(jìn)行分布式事務(wù)管理(測(cè)試代碼如下)

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.SQLException;

import javax.naming.InitialContext;

import javax.sql.DataSource;

import javax.transaction.SystemException;

import javax.transaction.UserTransaction;

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

//分布式事務(wù)處理

public class transferAccount

{

@SuppressWarnings("null")

public void testTransferAccount()

{

UserTransaction userts = null;

Connection connA = null;

PreparedStatement psA = null;

InitialContext context = null;

Connection connB = null;

PreparedStatement psB = null;

try

{

//獲得事務(wù)管理對(duì)象

userts = (UserTransaction) context.lookup("java:comp/UserTransaction");

//獲取兩個(gè)數(shù)據(jù)庫(kù)

connA = getDataSourceA().getConnection();

connB = getDataSourceB().getConnection();

//開(kāi)啟事務(wù)

userts.begin();

//sql語(yǔ)句

psA = connA.prepareStatement("我加1");

psB = connB.prepareStatement("我減1");

//執(zhí)行sql

psA.executeUpdate();

psB.executeUpdate();

//事務(wù)提交

userts.commit();

} catch (Exception e)

{

try

{

userts.rollback();

} catch (IllegalStateException | SecurityException

| SystemException e1)

{

e1.printStackTrace();

}

e.printStackTrace();

}

finally

{

try

{

psA.close();

psB.close();

connA.close();

connB.close();

} catch (SQLException e)

{

e.printStackTrace();

}

}

}

public DataSource getDataSourceA()

{

MysqlDataSource dataSource = new MysqlDataSource();

dataSource.setDatabaseName("mysql");

dataSource.setServerName("server");

dataSource.setPortNumber(1433);

dataSource.setUser("test");

dataSource.setPassword("test");

return dataSource;

}

public DataSource getDataSourceB()

{

MysqlDataSource dataSource = new MysqlDataSource();

dataSource.setDatabaseName("mysql");

dataSource.setServerName("server");

dataSource.setPortNumber(1435);

dataSource.setUser("test1");

dataSource.setPassword("test1");

return dataSource;

}

}


名稱(chēng)欄目:java分布式事務(wù)代碼 java分布式事務(wù)解決方案
本文路徑:http://weahome.cn/article/doshpoe.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部