我在Android中使用sqlite事务:
SQLiteDatabase database = sqlite_helper.getWritableDatabase();
database.beginTransaction();
...
database.setTransactionSuccessful();
database.endTransaction();
我的问题是:
1.我应该将endTransaction()
放在finally代码块中,如下所示:
try {
database.beginTransaction();
...
database.setTransactionSuccessful();
}
finally {
database.endTransaction();
}
如果在数据库操作期间出现异常,数据库是否会在不使用“finally”的情况下自动回滚?
android.database.sqlite.SQLiteMisuseException: library routine called out of sequence:
,编译时
有没有人帮我回答这些问题?非常感谢!
答案 0 :(得分:5)
1.您应该始终将endTransaction置于finally块
中2. SQLite中的事务是线程安全的,请参阅文档http://www.sqlite.org/atomiccommit.html
答案 1 :(得分:1)
您应始终将endTransaction()
放入finally
块(另请参阅the docs)。
否则,数据库将无法注意到发生了异常。
结束事务的唯一方法是关闭连接,在这种情况下,SQLite会自动回滚任何活动事务。
只要一个连接写入数据库(这意味着事务处于活动状态),就不能读取或写入其他连接。因此,您应该注意不要忘记结束交易。
你永远不应该从多个线程写;如果一个线程结束事务而另一个线程仍然在写,会发生什么?
您的SQLiteMisuseException
可能与您有关;没有看到代码就不可能说。
答案 2 :(得分:0)
是的,您应该使用finally块。这是我使用的一种简单的线程安全方法:
interface Props extends InterfaceState {
rectWidth: number
spaceBetweenRects: number
}
export class Labels extends React.Component<Props> {
render() {
const { rectWidth, labelRectHeight, spaceBetweenRects } = this.props
const names = ['Cher', 'Madonna', 'Band Names That Are Ridiculously Long', 'U2']
const rectHeight = labelRectHeight
const paddingLeftRight = 0.05 * rectWidth
const plusWidth = rectHeight / 2
return (
<g>
{names.map((name, i) => {
const y = i * labelRectHeight + i * spaceBetweenRects
const maxTextwidth = rectWidth - plusWidth - 3 * paddingLeftRight // this is the maximum length that text can have
return (
<g key={i}>
<React.Fragment>
<rect x={0} y={y} width={rectWidth} height={rectHeight} fill={'#E4E9EB'} />
</React.Fragment>
<text
ref={this.textRef}
x={rectWidth - paddingLeftRight}
y={y + rectHeight / 2}
textAnchor="end"
alignmentBaseline="middle"
>
{name}
</text>
</g>
)
})}
</g>
)
}
}
synchronized 关键字将方法及其包含对象锁定,从而使其线程安全...