0

Я пишу приложение Java, которое запускает асинхронные потоки для чтения и обновления значений из одной базы данных. Каждый поток получает соединение из пула соединений (c3p0). Я должен предотвратить условия гонки, потому что мне нужно обновлять записи на основе их текущих значений. Поэтому чтение данных с помощью оператора SELECT, а затем его обновление с помощью инструкции UPDATE вызовет условие гонки, и поэтому оно не будет потокобезопасным. Я уже нашел некоторые решения, как предотвратить такие условия гонки, но у меня все еще есть некоторые вопросы.Java MySQL предотвращает состояние гонки

Например, я могу использовать вид UPDATE ExampleTable SET ExampleValue = ExampleValue + '5' WHERE Id = '10' для увеличения значений потокобезопасности. Я читал, что это атомное утверждение. Поэтому мой первый вопрос: Выполняет ли PreparedStatement в java всегда потокобезопасный? Я так думаю, потому что (если autoCommit верно), каждый отдельный исполняемый оператор является транзакцией, а транзакции являются атомарными, верно? Если да, это также случай, если я вызываю процедуру с выражением или если я помещаю несколько запросов в один оператор, разделенный точкой с запятой?

Я также прочитал, что я могу установить autoCommit в false и выполнить несколько операторов перед выполнением, что также обеспечивает безопасность потоков, поскольку никакая другая инструкция не может прервать транзакцию. Это правильно?

Есть ли какие-либо дополнительные решения для предотвращения таких условий гонки?

+0

Я думаю, что [это] (http://stackoverflow.com/a/2713427/898478) отвечает на некоторые из ваших вопросов, вы его проверяли? Специально: * «Дайте каждой теме свое собственное соединение» *. Я делаю это через пул соединений, и у меня нет условий гонки (хотя я использую PostgreSQL, а не MySQL). – m0skit0

+0

Я использую Пул соединений, и каждый поток имеет свой собственный объект Connection из пула. Но условия гонки все еще возможны при использовании отдельных инструкций для чтения и письма. – stonar96

+0

Как отвечает EJP, используйте 'SELECT FOR UPDATE', таким образом вы имеете только одно утверждение. Если вы хотите выполнить больше запросов/обновлений или 'SELECT FOR UPDATE', это не вариант, вам необходимо обернуть их в транзакцию (конечно же, одно соединение на поток). – m0skit0

ответ

1

Выполняет PreparedStatement в java всегда в потоковом режиме?

Я не уверен, что это значит. Вы использовали бы только PreparedStatement и действительно его базовый Connection из одного потока, поэтому проблема не возникает.

Я так думаю, потому что (если autoCommit является истинным) каждый отдельный выполненный оператор является транзакцией, а транзакции являются атомарными, верно? Если да, это также случай, если я вызываю процедуру с выражением или если я помещаю несколько запросов в один оператор, разделенный точкой с запятой?

Я так и думал. То, что вы действительно спрашиваете, является ли PreparedStatementatomic, ли через потоки или процессы, а ответ на это «нет», если вы не используете автоматическую фиксацию. Если вы используете транзакции, это транзакция, которая является атомарной. [На самом деле это всегда сделка, которая является атомарной, но в режиме автоматической фиксации она совмещена с заявлением.]

Я также читал, что я могу установить Autocommit ложь и выполнить несколько операторов BEFOR совершали , который также обеспечивает безопасность потоков, поскольку никакое другое заявление не может прервать транзакцию. Это правильно?

Он достигает atomicity. Безопасность резьбы - это совсем другое дело.

Возможно, вы ищете SELECT... FOR UPDATE в рамках неавтомобильной сделки. Он блокирует возвращенные строки, чтобы они не могли быть возвращены другим таким заявлением до тех пор, пока эта транзакция не будет выполнена. Или такие конструкции, как INSERT ... ON DUPLICATE KEY [IGNORE|UPDATE].

+0

Как насчет нескольких утверждений? – m0skit0

+0

Вы имеете в виду, что я не должен использовать auto-commit вообще? Разве autoCommit не установлен по умолчанию? Можете ли вы ответить на другие вопросы? Выполняет ли один оператор всегда потокобезопасный? – stonar96

+0

@ stonar96 Ответ, который я связал, уже отвечает на вопрос «одного утверждения». – m0skit0

Смежные вопросы