首先要說明的一點(diǎn)是Spring的事務(wù)注解可以寫在controller 也可以寫在service層,下次見到寫在controller層的事務(wù)注解不要驚訝....
注解失敗的情況1
service層普通方法(testDeleteUser)調(diào)用帶注解(deleteUserRunningTimeException)的方法,發(fā)生運(yùn)行時(shí)異常后,回滾失敗
解決辦法:
普通方法(testDeleteUser)也加上注解
注:
如果在方法里進(jìn)行了異常捕獲,一定要拋出去,否則回滾依然不會(huì)生效
@Transactional
public void deleteUserRunningTimeException(int id) {
try {
usersDao.deleteUserById(id);
int num = 1 / 0;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
/**
* 普通方法調(diào)用注解方法
*/
//@Transactional
public void testDeleteUser(int id) {
deleteUserRunningTimeException(id);
}
注解失敗的情況2
service層方法報(bào)了非運(yùn)行時(shí)異常,回滾操作失敗
解決辦法:
方法添加注解,聲明為Exception類型進(jìn)行回滾
@Transactional(rollbackFor = Exception.class),同樣,如果捕獲了異常,必須拋出去,否則回滾不會(huì)生效
/**
* 測試非運(yùn)行時(shí)異常,是否回滾
* @param id
*/
@Transactional(rollbackFor = Exception.class)
public void deleteUserSimpleException(int id) throws Exception {
FileReader fileReader = null;
try {
usersDao.deleteUserById(id);
//創(chuàng)建要讀取的數(shù)據(jù)文件的文件對(duì)象 file
File file = new File("d:\\data.txt");
//創(chuàng)建要讀取數(shù)據(jù)的輸入流
fileReader = new FileReader(file);
//從輸入流中讀取一個(gè)字符;
int c = fileReader.read();
//判斷是否讀取到文件結(jié)束,如果讀取到文件的最后會(huì)返回-1
while (c!=-1) {
//輸出讀取的這個(gè)字符
System.out.println((char)c);
//再讀取下一個(gè)字符
c = fileReader.read();
}
} catch (Exception e) {
e.printStackTrace();
try {
if (fileReader != null) {
fileReader.close();
fileReader = null;
}
} catch (Exception e2) {
e2.printStackTrace();
}
} finally {
try {
if (fileReader != null) {
fileReader.close();
fileReader = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 普通方法調(diào)用注解方法
*/
@Transactional(rollbackFor = Exception.class)
public void testDeleteUser(int id) throws Exception {
deleteUserSimpleException(id);
}
注解失敗的情況2.1
實(shí)際項(xiàng)目中,并不會(huì)對(duì)每一個(gè)方法進(jìn)行仔細(xì)的排查,再?zèng)Q定使用哪種注解,只需要捕獲異常后拋出運(yùn)行時(shí)異常就可以完成回滾操作
注:
這種方式注解就不需要指定某種類型的異常了,默認(rèn)就是對(duì)運(yùn)行時(shí)異常進(jìn)行回滾
/**
* 測試非運(yùn)行時(shí)異常,是否回滾
* @param id
*/
@Transactional
public void deleteUserSimpleException2(int id) {
FileReader fileReader = null;
try {
usersDao.deleteUserById(id);
//創(chuàng)建要讀取的數(shù)據(jù)文件的文件對(duì)象 file
File file = new File("d:\\data.txt");
//創(chuàng)建要讀取數(shù)據(jù)的輸入流
fileReader = new FileReader(file);
//從輸入流中讀取一個(gè)字符;
int c = fileReader.read();
//判斷是否讀取到文件結(jié)束,如果讀取到文件的最后會(huì)返回-1
while (c!=-1) {
//輸出讀取的這個(gè)字符
System.out.println((char)c);
//再讀取下一個(gè)字符
c = fileReader.read();
}
} catch (Exception e) {
e.printStackTrace();
try {
if (fileReader != null) {
fileReader.close();
fileReader = null;
}
} catch (Exception e2) {
e2.printStackTrace();
}
throw new RuntimeException(e.getCause());
} finally {
try {
if (fileReader != null) {
fileReader.close();
fileReader = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 普通方法調(diào)用注解方法
*/
@Transactional
public void testDeleteUser(int id) {
deleteUserSimpleException2(id);
}
注解的用法
注解可以寫在類聲明上,也可以寫在方法上,寫在類聲明上的時(shí)候表示調(diào)用該類的所有方法時(shí)都會(huì)啟動(dòng)事務(wù),如果對(duì)個(gè)別方法有事務(wù)的個(gè)性化定制,則可以在方法上寫注解,會(huì)按照就近原則執(zhí)行注解
@Service
@Transactional(readOnly = true)
public class UserServiceImpl {
/**
* 測試非運(yùn)行時(shí)異常,是否回滾
* @param id
*/
@Transactional(rollbackFor = Exception.class)
public void deleteUserSimpleException(int id) throws Exception {
FileReader fileReader = null;
try {
usersDao.deleteUserById(id);
//創(chuàng)建要讀取的數(shù)據(jù)文件的文件對(duì)象 file
File file = new File("d:\\data.txt");
//創(chuàng)建要讀取數(shù)據(jù)的輸入流
fileReader = new FileReader(file);
//從輸入流中讀取一個(gè)字符;
int c = fileReader.read();
//判斷是否讀取到文件結(jié)束,如果讀取到文件的最后會(huì)返回-1
while (c!=-1) {
//輸出讀取的這個(gè)字符
System.out.println((char)c);
//再讀取下一個(gè)字符
c = fileReader.read();
}
} catch (Exception e) {
e.printStackTrace();
try {
if (fileReader != null) {
fileReader.close();
fileReader = null;
}
} catch (Exception e2) {
e2.printStackTrace();
}
} finally {
try {
if (fileReader != null) {
fileReader.close();
fileReader = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
注解屬性(readOnly = true)
當(dāng)注解中出現(xiàn)readOnly=true時(shí),通常用于多表多表多表查詢,數(shù)據(jù)庫執(zhí)行SQL時(shí),會(huì)保證數(shù)據(jù)的一致性,查到的資料有說設(shè)置為true進(jìn)行查詢時(shí),會(huì)提升性能,可能是我測試庫數(shù)據(jù)量小的緣故,看不出區(qū)別
readOnly屬性默認(rèn)為false